From d0e826733eb9c9661ddfa3f8d0c8a86983be2fb4 Mon Sep 17 00:00:00 2001 From: Xykota Date: Tue, 26 Sep 2023 16:14:37 +0700 Subject: [PATCH] deploy(hardhat): v1.12.0 --- .../hardhat/deployments/arbitrum/Curve.json | 28 +- .../deployments/arbitrum/DiamondCutFacet.json | 28 +- .../arbitrum/DiamondLoupeFacet.json | 26 +- .../arbitrum/DiamondMultiInit.json | 28 +- .../deployments/arbitrum/InitLibWarp.json | 33 +- .../deployments/arbitrum/KittyFacet.json | 26 +- .../deployments/arbitrum/OwnershipFacet.json | 26 +- .../deployments/arbitrum/UniV2LikeFacet.json | 28 +- .../deployments/arbitrum/UniV3Callback.json | 28 +- .../deployments/arbitrum/UniV3Like.json | 26 +- .../deployments/arbitrum/WarpLink.json | 265 ++--------------- .../025166ddb0f771753ceec554ac05c5f7.json | 161 ++++++++++ .../4bd33b0efaadcd28492d25c3625ab942.json | 191 ++++++++++++ .../df6263755b6a66e75866b356448256e7.json | 119 ++++++++ .../hardhat/deployments/mainnet/Curve.json | 26 +- .../deployments/mainnet/DiamondCutFacet.json | 26 +- .../mainnet/DiamondLoupeFacet.json | 26 +- .../deployments/mainnet/DiamondMultiInit.json | 24 +- .../deployments/mainnet/InitLibWarp.json | 33 +- .../deployments/mainnet/InitUniV2Router.json | 26 +- .../deployments/mainnet/KittyFacet.json | 26 +- .../deployments/mainnet/OwnershipFacet.json | 26 +- .../deployments/mainnet/UniV2LikeFacet.json | 28 +- .../deployments/mainnet/UniV2RouterFacet.json | 26 +- .../deployments/mainnet/UniV3Callback.json | 26 +- .../deployments/mainnet/UniV3Like.json | 26 +- .../hardhat/deployments/mainnet/WarpLink.json | 265 ++--------------- .../025166ddb0f771753ceec554ac05c5f7.json | 161 ++++++++++ .../4bd33b0efaadcd28492d25c3625ab942.json | 191 ++++++++++++ .../df6263755b6a66e75866b356448256e7.json | 119 ++++++++ .../hardhat/deployments/optimism/Curve.json | 26 +- .../deployments/optimism/DiamondCutFacet.json | 26 +- .../optimism/DiamondLoupeFacet.json | 26 +- .../optimism/DiamondMultiInit.json | 24 +- .../deployments/optimism/InitLibWarp.json | 33 +- .../deployments/optimism/KittyFacet.json | 26 +- .../deployments/optimism/OwnershipFacet.json | 26 +- .../deployments/optimism/UniV2LikeFacet.json | 28 +- .../deployments/optimism/UniV3Callback.json | 26 +- .../deployments/optimism/UniV3Like.json | 26 +- .../deployments/optimism/WarpLink.json | 265 ++--------------- .../025166ddb0f771753ceec554ac05c5f7.json | 161 ++++++++++ .../4bd33b0efaadcd28492d25c3625ab942.json | 191 ++++++++++++ .../df6263755b6a66e75866b356448256e7.json | 119 ++++++++ .../hardhat/deployments/polygon/Curve.json | 42 +-- .../deployments/polygon/DiamondCutFacet.json | 42 +-- .../polygon/DiamondLoupeFacet.json | 42 +-- .../deployments/polygon/DiamondMultiInit.json | 42 +-- .../deployments/polygon/InitLibWarp.json | 49 +-- .../deployments/polygon/KittyFacet.json | 42 +-- .../deployments/polygon/OwnershipFacet.json | 50 ++-- .../deployments/polygon/UniV2LikeFacet.json | 44 +-- .../deployments/polygon/UniV3Callback.json | 42 +-- .../deployments/polygon/UniV3Like.json | 42 +-- .../hardhat/deployments/polygon/WarpLink.json | 281 +++--------------- .../025166ddb0f771753ceec554ac05c5f7.json | 161 ++++++++++ .../4bd33b0efaadcd28492d25c3625ab942.json | 191 ++++++++++++ .../df6263755b6a66e75866b356448256e7.json | 119 ++++++++ packages/hardhat/package.json | 2 +- 59 files changed, 2677 insertions(+), 1585 deletions(-) create mode 100644 packages/hardhat/deployments/arbitrum/solcInputs/025166ddb0f771753ceec554ac05c5f7.json create mode 100644 packages/hardhat/deployments/arbitrum/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json create mode 100644 packages/hardhat/deployments/arbitrum/solcInputs/df6263755b6a66e75866b356448256e7.json create mode 100644 packages/hardhat/deployments/mainnet/solcInputs/025166ddb0f771753ceec554ac05c5f7.json create mode 100644 packages/hardhat/deployments/mainnet/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json create mode 100644 packages/hardhat/deployments/mainnet/solcInputs/df6263755b6a66e75866b356448256e7.json create mode 100644 packages/hardhat/deployments/optimism/solcInputs/025166ddb0f771753ceec554ac05c5f7.json create mode 100644 packages/hardhat/deployments/optimism/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json create mode 100644 packages/hardhat/deployments/optimism/solcInputs/df6263755b6a66e75866b356448256e7.json create mode 100644 packages/hardhat/deployments/polygon/solcInputs/025166ddb0f771753ceec554ac05c5f7.json create mode 100644 packages/hardhat/deployments/polygon/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json create mode 100644 packages/hardhat/deployments/polygon/solcInputs/df6263755b6a66e75866b356448256e7.json diff --git a/packages/hardhat/deployments/arbitrum/Curve.json b/packages/hardhat/deployments/arbitrum/Curve.json index c65b21a6..5685b19b 100644 --- a/packages/hardhat/deployments/arbitrum/Curve.json +++ b/packages/hardhat/deployments/arbitrum/Curve.json @@ -1,5 +1,5 @@ { - "address": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", + "address": "0xd1d6a41f4Ab623596D096803363AEf2f89336071", "abi": [ { "inputs": [], @@ -141,28 +141,28 @@ "type": "function" } ], - "transactionHash": "0x0105975e1fb771c3fe7d2be8f1aded512732bbd1bda9977c235bea973602296a", + "transactionHash": "0xb44ad5e88a1216d5b91fbe87a11f53f53751d08ac24f73ba8346f69a25453c0b", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", - "transactionIndex": 4, - "gasUsed": "4547733", + "contractAddress": "0xd1d6a41f4Ab623596D096803363AEf2f89336071", + "transactionIndex": 1, + "gasUsed": "4060402", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x99857e3ab14153dc0f2ea81e3cd9fc9c5d7578a97d101e63bae7c81ed4439f66", - "transactionHash": "0x0105975e1fb771c3fe7d2be8f1aded512732bbd1bda9977c235bea973602296a", + "blockHash": "0x43271def2ee0faad2fd677b9de7c3c4b8c9ec12c21a8b8dfa0895cab2755ecd8", + "transactionHash": "0xb44ad5e88a1216d5b91fbe87a11f53f53751d08ac24f73ba8346f69a25453c0b", "logs": [], - "blockNumber": 133037936, - "cumulativeGasUsed": "5496899", + "blockNumber": 134650561, + "cumulativeGasUsed": "4060402", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26a236ab658af7341bd585a6fd11474bb627ba050aca1c08532cd29c72d314c9\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x377723b233f7e22e77f9b0da81d8fb8f78d5adcdb6bb7817f06e602dea6f182e\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb8f29211d45827b00c6c594b8f0b68517a33881f55d8988a06d0721df488ce12\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x7439d7d6a66ec29616591dcfe8252bd92ec4852f58edcfb9b1e7102d1d43b74c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/DiamondCutFacet.json b/packages/hardhat/deployments/arbitrum/DiamondCutFacet.json index 7a7aca47..e138f182 100644 --- a/packages/hardhat/deployments/arbitrum/DiamondCutFacet.json +++ b/packages/hardhat/deployments/arbitrum/DiamondCutFacet.json @@ -1,5 +1,5 @@ { - "address": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", + "address": "0x56b990b4909E916E1dA74294D8b67ED045402313", "abi": [ { "inputs": [ @@ -100,28 +100,28 @@ "type": "function" } ], - "transactionHash": "0x017698903716add81ead9371e1d05efd4cbdfef15f135d6b84a2dcf5afd63d50", + "transactionHash": "0xc526c88e0a83590c1f1d000a51301d796d68e98724a9b25768befa58d181681f", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", - "transactionIndex": 4, - "gasUsed": "5263849", + "contractAddress": "0x56b990b4909E916E1dA74294D8b67ED045402313", + "transactionIndex": 2, + "gasUsed": "4495719", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6c29b58c2f5c5826440d498409e6641d93850ea3caf3fd760ddb876143e2e05f", - "transactionHash": "0x017698903716add81ead9371e1d05efd4cbdfef15f135d6b84a2dcf5afd63d50", + "blockHash": "0x4426e0079360791d92d84ec29471dc255620e39f5d4ac5dcb052076073c55abc", + "transactionHash": "0xc526c88e0a83590c1f1d000a51301d796d68e98724a9b25768befa58d181681f", "logs": [], - "blockNumber": 130349400, - "cumulativeGasUsed": "10382500", + "blockNumber": 134650136, + "cumulativeGasUsed": "5804937", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x862ac209f7309608ba3e033d6f2e185d82936745ae9eff95d78681bd7c09799a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0xfb51534d56cfbfc884869f4c67b3b01fb3303a762418d796feabb78543d289ee\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/arbitrum/DiamondLoupeFacet.json b/packages/hardhat/deployments/arbitrum/DiamondLoupeFacet.json index cc7cd0f9..001ff05c 100644 --- a/packages/hardhat/deployments/arbitrum/DiamondLoupeFacet.json +++ b/packages/hardhat/deployments/arbitrum/DiamondLoupeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", + "address": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", "abi": [ { "inputs": [ @@ -78,28 +78,28 @@ "type": "function" } ], - "transactionHash": "0x8941b3f54ae704ada1bff0c21040836a32eb210af503d94266c754ef0c51c944", + "transactionHash": "0xc3960663122cb660778ff2b8332dd7bfc9d1f399cb8ceceffa0e625bc779dece", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", + "contractAddress": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", "transactionIndex": 1, - "gasUsed": "1967114", + "gasUsed": "1649911", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x10cc385ebb93fa3f27587572667bead6651366bb556fd0c5f013ec02bdc12bb8", - "transactionHash": "0x8941b3f54ae704ada1bff0c21040836a32eb210af503d94266c754ef0c51c944", + "blockHash": "0xa6587f2643bf98fc396731050262a7ae6fb4b5d3112c9b2d5e9f5eb43aa7ee3d", + "transactionHash": "0xc3960663122cb660778ff2b8332dd7bfc9d1f399cb8ceceffa0e625bc779dece", "logs": [], - "blockNumber": 130349825, - "cumulativeGasUsed": "1967114", + "blockNumber": 134650192, + "cumulativeGasUsed": "1649911", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x912f2287b015cd1568157eb79d48033d8db3be846de4c50691d44ad5dc1a638b\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x5edfd8138efb21086b53df2028f755aae576b00a7193102cca00d14beb025475\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/arbitrum/DiamondMultiInit.json b/packages/hardhat/deployments/arbitrum/DiamondMultiInit.json index c556aac4..5de917a2 100644 --- a/packages/hardhat/deployments/arbitrum/DiamondMultiInit.json +++ b/packages/hardhat/deployments/arbitrum/DiamondMultiInit.json @@ -1,5 +1,5 @@ { - "address": "0x88fA496FD35AC5e20D8e59Afc3432197BB10b6F1", + "address": "0xb88582B085a7ce62Ad41FAd01737140e8Ea95f78", "abi": [ { "inputs": [ @@ -52,28 +52,28 @@ "type": "function" } ], - "transactionHash": "0xc164e1413f64181532625356b3d573015e684a48e91eb53bde1a0a3bddfda7b3", + "transactionHash": "0x423a8b6912b2b978fa97fdaa498c95588c651716ad7956ab33bd542e6c6bf2ec", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x88fA496FD35AC5e20D8e59Afc3432197BB10b6F1", - "transactionIndex": 3, - "gasUsed": "1617485", + "contractAddress": "0xb88582B085a7ce62Ad41FAd01737140e8Ea95f78", + "transactionIndex": 4, + "gasUsed": "1383794", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfdf6d8d445a80fcf62d63da4c29b473490ab11a42a567d8575f5a088e610f518", - "transactionHash": "0xc164e1413f64181532625356b3d573015e684a48e91eb53bde1a0a3bddfda7b3", + "blockHash": "0xb13dd0d31b319899cb256ad975255a92eebb487d602dd492c2c2d1e5707ee1b3", + "transactionHash": "0x423a8b6912b2b978fa97fdaa498c95588c651716ad7956ab33bd542e6c6bf2ec", "logs": [], - "blockNumber": 130350792, - "cumulativeGasUsed": "2969694", + "blockNumber": 134650633, + "cumulativeGasUsed": "4953723", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7039f6a07145a76f91a7f976a7f6af7fba83d559a3f895e6c425fe1fbd239fce\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8a6197389eba7856703a1fbabf7ecdd760678fcaf61be646731a14e4f88e80e9\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/InitLibWarp.json b/packages/hardhat/deployments/arbitrum/InitLibWarp.json index aeda189e..489bbb46 100644 --- a/packages/hardhat/deployments/arbitrum/InitLibWarp.json +++ b/packages/hardhat/deployments/arbitrum/InitLibWarp.json @@ -1,5 +1,5 @@ { - "address": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", + "address": "0xAed6fe85bb7fA0761FfbB9D85cd2E39E5038e7c5", "abi": [ { "inputs": [ @@ -12,6 +12,11 @@ "internalType": "address", "name": "permit2", "type": "address" + }, + { + "internalType": "address", + "name": "router", + "type": "address" } ], "name": "init", @@ -20,28 +25,28 @@ "type": "function" } ], - "transactionHash": "0xebbde1057c92862af912d5eaebe0e9a127f244daf94f49e5514a9b2161a61136", + "transactionHash": "0xfcd3d5c46cf3c2a9e378edd1d1c8d7c734047a2778e8e094e712d73670b70c6f", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", - "transactionIndex": 2, - "gasUsed": "657678", + "contractAddress": "0xAed6fe85bb7fA0761FfbB9D85cd2E39E5038e7c5", + "transactionIndex": 1, + "gasUsed": "637289", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc52e602833014ec924f0aef2226cd2be05bc204bbcb07165de893ec8e3c6564f", - "transactionHash": "0xebbde1057c92862af912d5eaebe0e9a127f244daf94f49e5514a9b2161a61136", + "blockHash": "0xa929cb373895c0308a6175ec8b6bbb56c855d5976d41ba05612fdeda44eb96b6", + "transactionHash": "0xfcd3d5c46cf3c2a9e378edd1d1c8d7c734047a2778e8e094e712d73670b70c6f", "logs": [], - "blockNumber": 133037955, - "cumulativeGasUsed": "892278", + "blockNumber": 134650611, + "cumulativeGasUsed": "637289", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0x8e3d3c6cee0d946dec6ad0cb6ff3f9c902771d51868ec082a9aa440bd84685ad\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610163806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2, address router) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n s.stargateRouter = IStargateRouter(router);\\n }\\n}\\n\",\"keccak256\":\"0xd9e7e1bf8fc13c1490d02df612a04e30f3ad189728f67888d4ab6ad884e30d43\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/KittyFacet.json b/packages/hardhat/deployments/arbitrum/KittyFacet.json index a3f03207..45431bb0 100644 --- a/packages/hardhat/deployments/arbitrum/KittyFacet.json +++ b/packages/hardhat/deployments/arbitrum/KittyFacet.json @@ -1,5 +1,5 @@ { - "address": "0x208F4e08017b66AFCFA14Be44e85ee21bB025707", + "address": "0x61f07f3BA9ba01B500947E10531f9F42706E991c", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0xb106d9d09cbfa650febd7e0247f85ca77e999281831a6a2d6635b79d301c297e", + "transactionHash": "0xe00ca98d17342e9d1476f716d2fb5019b10a07b98c84968e3eec35f75ae11a33", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x208F4e08017b66AFCFA14Be44e85ee21bB025707", + "contractAddress": "0x61f07f3BA9ba01B500947E10531f9F42706E991c", "transactionIndex": 1, - "gasUsed": "3297242", + "gasUsed": "2782927", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x44bb72f2babb0738c59c160ce9ab3596a50feca5f063df1c057d8c1f461c74a5", - "transactionHash": "0xb106d9d09cbfa650febd7e0247f85ca77e999281831a6a2d6635b79d301c297e", + "blockHash": "0xe8ff3a30fe73f580bd29e0028bade67d274b1418eb1015d63cf7fc0daa0954e9", + "transactionHash": "0xe00ca98d17342e9d1476f716d2fb5019b10a07b98c84968e3eec35f75ae11a33", "logs": [], - "blockNumber": 130350002, - "cumulativeGasUsed": "3297242", + "blockNumber": 134650292, + "cumulativeGasUsed": "2782927", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b2dbdcc0b6941fae124c7dae9af5f1726bb6c522b1bb92b1dede393f5927230\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0xcf24bb7018a505bbb0f35146f9793f6ef407ce11a998817aff570a66e7848b98\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0xa4b787bb171f2fd5cba3310a8cee7eee32e4ab06f5902a6fcd62273c551115ed\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3abf20697535d8feceedd82cbde3105a9e6a6c6ddfc75532a588bca369ab520d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0x6cf80a254d66f174fc82fdc474aea1b71dad36e3a6cf0e2353e2298e04041ce2\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0x9b80854a259f0f4fe4e72968297f1d28afe40d9c62a6d59df007568be79f8b02\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/OwnershipFacet.json b/packages/hardhat/deployments/arbitrum/OwnershipFacet.json index 13913744..5b3d5989 100644 --- a/packages/hardhat/deployments/arbitrum/OwnershipFacet.json +++ b/packages/hardhat/deployments/arbitrum/OwnershipFacet.json @@ -1,5 +1,5 @@ { - "address": "0x2B7327b37F48fEa6D2063C9c03fC7250ecA56955", + "address": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", "abi": [ { "anonymous": false, @@ -47,28 +47,28 @@ "type": "function" } ], - "transactionHash": "0x0840b889d022bcc0d28dc115e0a27cadc73d71048e8cd7fc7dde3981aa2b1cc3", + "transactionHash": "0x0fdb44a10bca282ad2ce13ff7b5bc5750321b20d3bff8a7db5a3dce6877434d0", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x2B7327b37F48fEa6D2063C9c03fC7250ecA56955", + "contractAddress": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", "transactionIndex": 1, - "gasUsed": "1031671", + "gasUsed": "861183", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd3eec2a854ddce6b759af923f538f2909b1deee6a19883f9ab49e08688d49751", - "transactionHash": "0x0840b889d022bcc0d28dc115e0a27cadc73d71048e8cd7fc7dde3981aa2b1cc3", + "blockHash": "0xe42b4af7c161d512c15932f6e77ae5dd32dc3cde23d3828ba75977a7b7dec7ce", + "transactionHash": "0x0fdb44a10bca282ad2ce13ff7b5bc5750321b20d3bff8a7db5a3dce6877434d0", "logs": [], - "blockNumber": 130349919, - "cumulativeGasUsed": "1031671", + "blockNumber": 134650263, + "cumulativeGasUsed": "861183", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0x2836ab3ca2aebaaffbafed73912c31012d34b0a20860394fd7050199401de018\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0xd14213dfd60c9476041ad22fcb96d4d81cda561979c24befa9de88220dae51d2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", "devdoc": { "events": { "OwnershipTransferred(address,address)": { diff --git a/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json b/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json index c5a66db0..46d2776f 100644 --- a/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/arbitrum/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x23AB6D003341883D6D3f31192702F5B35995596F", + "address": "0xF83C7f55c2f1D2c1e83b539d5C925E4C0cC49435", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0xb317648356ca6462b570cd9f4be005f3590cc2628add1c84a6397297127fe7dd", + "transactionHash": "0x350676a4f9c789e589d3807959ab574f2b234038a50a986868948411539ec99d", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x23AB6D003341883D6D3f31192702F5B35995596F", - "transactionIndex": 3, - "gasUsed": "6851164", + "contractAddress": "0xF83C7f55c2f1D2c1e83b539d5C925E4C0cC49435", + "transactionIndex": 2, + "gasUsed": "6137634", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x784009f03f2727affdcd70ca19e4faca80094d94957b048bede09d2a01dd3f53", - "transactionHash": "0xb317648356ca6462b570cd9f4be005f3590cc2628add1c84a6397297127fe7dd", + "blockHash": "0x56d7edd9cd2cb808daa81a25fb0c619d23c40f527f7211c059b4100844a06ea0", + "transactionHash": "0x350676a4f9c789e589d3807959ab574f2b234038a50a986868948411539ec99d", "logs": [], - "blockNumber": 133037867, - "cumulativeGasUsed": "8280820", + "blockNumber": 134650346, + "cumulativeGasUsed": "6668484", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56e7341e6a317f670cc3df2ee1e18b3a47c8e11f302db67b787aba91007d2280\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xcf11728bd04fa6c509bfa1093d6e6f9490a1b2fb41a94144d13d0c0abe3db24a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xea45669f18797f167c70a3fc6ee194fa38fea7a14d310045083d2b64bb88397d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x8dec0c768b0e3875e1e59d241435bcdf88de646aa674ad20c26204d166d6acc9\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/UniV3Callback.json b/packages/hardhat/deployments/arbitrum/UniV3Callback.json index 0b10d186..d5d27910 100644 --- a/packages/hardhat/deployments/arbitrum/UniV3Callback.json +++ b/packages/hardhat/deployments/arbitrum/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0xd8c18A7CcA4576156dD6d11132799E649A591B3E", + "address": "0xC934b2636ACF7803eb75964fEb88797D5EEA1b2a", "abi": [ { "inputs": [], @@ -53,28 +53,28 @@ "type": "function" } ], - "transactionHash": "0x00a4bcdf12500602f141d5d9bc971720c6378bc0b974c5cad3150fed7d799ad8", + "transactionHash": "0x5970aaa61ed466cecdc612e6676a40afc2fff16863046e2f117cfa7b7673aa0a", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd8c18A7CcA4576156dD6d11132799E649A591B3E", - "transactionIndex": 3, - "gasUsed": "1999257", + "contractAddress": "0xC934b2636ACF7803eb75964fEb88797D5EEA1b2a", + "transactionIndex": 1, + "gasUsed": "1772958", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa53b7a580a9af4ed4723c54f568b218e95386fd9427837d953463cd0242d11ca", - "transactionHash": "0x00a4bcdf12500602f141d5d9bc971720c6378bc0b974c5cad3150fed7d799ad8", + "blockHash": "0xf99ada8b79ff1eb98e7dfb17eb7574c49ccb10ae117effa9b0c3190b1346e1cd", + "transactionHash": "0x5970aaa61ed466cecdc612e6676a40afc2fff16863046e2f117cfa7b7673aa0a", "logs": [], - "blockNumber": 133037885, - "cumulativeGasUsed": "2605874", + "blockNumber": 134650392, + "cumulativeGasUsed": "1772958", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/UniV3Like.json b/packages/hardhat/deployments/arbitrum/UniV3Like.json index dd3bbb69..d499f8bb 100644 --- a/packages/hardhat/deployments/arbitrum/UniV3Like.json +++ b/packages/hardhat/deployments/arbitrum/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x9fEDE519d846E1165c843872C62f74c353a6Cfd1", + "address": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0xc227951db68195e36e96dc6cf5766e63d0e342ac1f68e051e6dae0d75509de33", + "transactionHash": "0x90fd849362bcf32cd68517a1b1720d39e5151030203bcd7eb087244c3b51b624", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x9fEDE519d846E1165c843872C62f74c353a6Cfd1", + "contractAddress": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", "transactionIndex": 1, - "gasUsed": "6300893", + "gasUsed": "5655898", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x35a2693d2d52fdb43fce7491562883883346c858ad766d2a72509c144160c356", - "transactionHash": "0xc227951db68195e36e96dc6cf5766e63d0e342ac1f68e051e6dae0d75509de33", + "blockHash": "0x73cbfbed10de60c27e3029f69b01d3e289bb7aaaa6b5106dd94fb6b5f6f99128", + "transactionHash": "0x90fd849362bcf32cd68517a1b1720d39e5151030203bcd7eb087244c3b51b624", "logs": [], - "blockNumber": 133037900, - "cumulativeGasUsed": "6300893", + "blockNumber": 134650444, + "cumulativeGasUsed": "5655898", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89bc1011edc38e6b0575be8b7f43aa2530bff8eaeff5da0ad1f479da30b0a84\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x3d5f724620e8dffd077b86613050bca34d60dab1288090558a63db18c8a8b9b1\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24d951973c414bf7384ab3c8862934f4ea125ba750c0f15f804325faa79a6a6c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xec1f28bdd5499b3065bebb77fa28e1a5b03dd07d22cb0273987f8f3dc9796096\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/WarpLink.json b/packages/hardhat/deployments/arbitrum/WarpLink.json index ad5f7ed8..46c639bf 100644 --- a/packages/hardhat/deployments/arbitrum/WarpLink.json +++ b/packages/hardhat/deployments/arbitrum/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0xc3A341353927a8b091b3ee68c745cdBe8E47a1b1", + "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", "abi": [ { "inputs": [], @@ -16,11 +16,6 @@ "name": "DeadlineExpired", "type": "error" }, - { - "inputs": [], - "name": "EthNotSupportedForWarp", - "type": "error" - }, { "inputs": [ { @@ -34,17 +29,17 @@ }, { "inputs": [], - "name": "InconsistentPartPayerOut", + "name": "IllegalJumpInSplit", "type": "error" }, { "inputs": [], - "name": "InconsistentPartTokenOut", + "name": "InconsistentPartPayerOut", "type": "error" }, { "inputs": [], - "name": "IncorrectEthValue", + "name": "InconsistentPartTokenOut", "type": "error" }, { @@ -54,261 +49,63 @@ }, { "inputs": [], - "name": "InsufficientOutputAmount", + "name": "InsufficientEthValue", "type": "error" }, { "inputs": [], - "name": "InsufficientTokensDelivered", + "name": "InsufficientOutputAmount", "type": "error" }, { "inputs": [], - "name": "NotEnoughParts", + "name": "InsufficientTokensDelivered", "type": "error" }, { "inputs": [], - "name": "UnexpectedPayerForWrap", + "name": "JumpMustBeLastCommand", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForUnwrap", + "name": "NativeTokenNotSupported", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForWrap", + "name": "NotEnoughParts", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenOut", + "name": "UnexpectedPayerForWrap", "type": "error" }, { "inputs": [], - "name": "UnexpectedValueAndTokenCombination", + "name": "UnexpectedTokenForUnwrap", "type": "error" }, { "inputs": [], - "name": "UnhandledCommand", + "name": "UnexpectedTokenForWrap", "type": "error" }, { "inputs": [], - "name": "UnhandledPoolKind", + "name": "UnexpectedTokenOut", "type": "error" }, { "inputs": [], - "name": "COMMAND_TYPE_SPLIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_UNWRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeSplit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeUnwrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpCurveExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledCommand", + "type": "error" }, { "inputs": [], - "name": "commandTypeWrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledPoolKind", + "type": "error" }, { "inputs": [ @@ -393,28 +190,28 @@ "type": "function" } ], - "transactionHash": "0xb3d054bbce6e90008189cba69a252cbd5ea034370784ad39d1d9f86af1990444", + "transactionHash": "0x6188175d3952b8b34b6194be87cb079cb90b46b567eecb275893c7b969d08f1a", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xc3A341353927a8b091b3ee68c745cdBe8E47a1b1", - "transactionIndex": 2, - "gasUsed": "10997636", + "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "transactionIndex": 1, + "gasUsed": "10480066", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdb63b6f6e2adec35e0c945994fc45920ad96d43e2cf717f975b97fcb77efbf7e", - "transactionHash": "0xb3d054bbce6e90008189cba69a252cbd5ea034370784ad39d1d9f86af1990444", + "blockHash": "0x8cec9e801a0bba2650cb9fb091c1cae765b60803fa22dab23e3a82a59bb5d30b", + "transactionHash": "0x6188175d3952b8b34b6194be87cb079cb90b46b567eecb275893c7b969d08f1a", "logs": [], - "blockNumber": 133037918, - "cumulativeGasUsed": "11655770", + "blockNumber": 134650513, + "cumulativeGasUsed": "10480066", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthNotSupportedForWarp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedValueAndTokenCombination\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_SPLIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_UNWRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeSplit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeUnwrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpCurveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract WarpLink is IWarpLink {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct TransientState {\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n }\\n\\n uint256 public constant COMMAND_TYPE_WRAP = 1;\\n uint256 public constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 public constant COMMAND_TYPE_SPLIT = 4;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 public constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n\\n function commandTypeWrap() external pure returns (uint256) {\\n return COMMAND_TYPE_WRAP;\\n }\\n\\n function commandTypeUnwrap() external pure returns (uint256) {\\n return COMMAND_TYPE_UNWRAP;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeSplit() external pure returns (uint256) {\\n return COMMAND_TYPE_SPLIT;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn != address(0)) {\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n TransientState memory t;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (msg.value == 0) {\\n if (params.tokenIn == address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n } else {\\n if (params.tokenIn != address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd9e99e7f5322f064977ea54517ad3889c4b74b1828d18c79e0490e06e2295a09\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedValueAndTokenCombination();\\n error UnexpectedPayerForWrap();\\n error EthNotSupportedForWarp();\\n error DeadlineExpired();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n\\n function commandTypeWrap() external pure returns (uint256);\\n\\n function commandTypeUnwrap() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeSplit() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa25e901022a1fc4f1bddb4e10cdce3a8963172ff1a8af9f4a2000ab0959876e7\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6c564dca55e92d9ee1c546a75a68d4e7c8799773f59f2aab4ea72cc70e601dff\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061409b806100206000396000f3fe60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "df6263755b6a66e75866b356448256e7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IllegalJumpInSplit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JumpMustBeLastCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nabstract contract WarpLinkCommandTypes {\\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\\n}\\n\\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct JumpStargateParams {\\n uint16 dstChainId;\\n uint256 srcPoolId;\\n uint256 dstPoolId;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n /**\\n * 0 or 1\\n */\\n uint256 jumped;\\n /**\\n * The amount of native value not spent. The native value starts off as\\n * `msg.value - params.amount` and is decreased by spending money on jumps.\\n *\\n * Any leftover native value is returned to `msg.sender`\\n */\\n uint256 nativeValueRemaining;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (tPart.jumped == 1) {\\n revert IllegalJumpInSplit();\\n }\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\n *\\n * The token must not be ETH (0)\\n *\\n * After this operation, the token will be unchanged and `t.amount` will\\n * be how much was sent. `t.jumped` will be set to `1` to indicate\\n * that no more commands should be run\\n *\\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\\n * because only `t.token` can be moved by Stargate.\\n *\\n * This command must not run inside of a split.\\n *\\n * A bridge fee must be paid in the native token. This fee is determined with\\n * `IStargateRouter.quoteLayerZeroFee`\\n *\\n * The value for `t.token` remains the same and is not chained.\\n *\\n * Params are read from the stream as:\\n * - dstChainId (uint16)\\n * - srcPoolId (uint8)\\n * - dstPoolId (uint8)\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n // NOTE: There is a WETH pool\\n revert NativeTokenNotSupported();\\n }\\n\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibKitty.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens\\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\\n }\\n\\n t.jumped = 1;\\n\\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // Max 5% slippage\\n _minAmountLD: (t.amount * 95) / 100,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(t.paramRecipient),\\n _payload: ''\\n });\\n\\n t.nativeValueRemaining = 0;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\\n if (commandIndex != commandCount - 1) {\\n revert JumpMustBeLastCommand();\\n }\\n\\n t = processJumpStargate(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramRecipient = params.recipient;\\n t.paramAmountOut = params.amountOut;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (params.tokenIn == address(0)) {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n t.nativeValueRemaining = msg.value - params.amountIn;\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n } else {\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n\\n t.nativeValueRemaining = msg.value;\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n if (t.jumped == 1) {\\n // The coins have jumped away from this chain. Fees were collected before the jump\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0be7a956a725d437c18e3bc2a96f09804a20c04d17feac9ac895b503152c13e2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error InsufficientEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedPayerForWrap();\\n error NativeTokenNotSupported();\\n error DeadlineExpired();\\n error IllegalJumpInSplit();\\n error JumpMustBeLastCommand();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n}\\n\",\"keccak256\":\"0x9242d5352942101b05bea1dcaea4b057473c4c2ae65214618f5361a18e194daa\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1c4eccca88e3487c6b6663ce51b77ea778e91b801373223e998fe96e2fff1750\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50614669806100206000396000f3fe60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/arbitrum/solcInputs/025166ddb0f771753ceec554ac05c5f7.json b/packages/hardhat/deployments/arbitrum/solcInputs/025166ddb0f771753ceec554ac05c5f7.json new file mode 100644 index 00000000..d03365ab --- /dev/null +++ b/packages/hardhat/deployments/arbitrum/solcInputs/025166ddb0f771753ceec554ac05c5f7.json @@ -0,0 +1,161 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and the amount will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * This command cannot run inside of a split\n *\n * No more commands should execute after this command since the tokens\n * have all left the chain\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * IStargateRouter.quoteLayerZeroFee\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint256)\n * - dstPoolId (uint256)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n // TODO: Make a new error or rename the existing\n revert EthNotSupportedForWarp();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // The value for `t.token` remains the same and is not chained. It is possible that the user\n // has constructed a command where the srcPoolId is not of the token t.token. This should not\n // be dangerous because only `t.token` is allowed to be transferred\n\n // Collect fees\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: uint16(params.dstChainId),\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // TODO: If the min amount is not met, is the tx reverted or is this refunded?\n _minAmountLD: 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encode(uint256(uint160(t.paramRecipient))),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2, address router) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n s.stargateRouter = IStargateRouter(router);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/arbitrum/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json b/packages/hardhat/deployments/arbitrum/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json new file mode 100644 index 00000000..d3c23a0d --- /dev/null +++ b/packages/hardhat/deployments/arbitrum/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json @@ -0,0 +1,191 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "contracts/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\n\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\n// The EIP-2535 Diamond standard requires these functions.\n\ncontract DiamondLoupeFacet is IDiamondLoupe {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; i++) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n }\n}\n" + }, + "contracts/facets/KittyFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IKitty} from '../interfaces/IKitty.sol';\n\ncontract KittyFacet is IKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n error InsufficientOwnerBalance(uint256 available);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\n LibKitty.State storage s = LibKitty.state();\n\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\n uint256 length = tokenSet.length();\n\n tokens_ = new address[](length);\n\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\n }\n }\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\n LibKitty.State storage s = LibKitty.state();\n\n return s.partnerBalances[partner][token];\n }\n\n function partnerWithdraw(address token) external {\n LibKitty.State storage s = LibKitty.state();\n\n uint256 balance = s.partnerBalances[msg.sender][token];\n\n if (balance > 0) {\n s.partnerBalances[msg.sender][token] = 0;\n s.partnerBalancesTotal[token] -= balance;\n\n emit PartnerWithdraw(msg.sender, token, balance);\n\n if (token == address(0)) {\n // NOTE: Control transfered to untrusted address\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n // NOTE: The token is not removed from the partner's token set\n IERC20(token).safeTransfer(msg.sender, balance);\n }\n }\n }\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\n LibDiamond.enforceIsContractOwner();\n\n LibKitty.State storage s = LibKitty.state();\n\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\n\n uint256 balance = token == address(0)\n ? address(this).balance\n : IERC20(token).balanceOf(address(this));\n\n uint256 available = balance - partnerBalanceTotal;\n\n if (amount > available) {\n revert InsufficientOwnerBalance(available);\n }\n\n if (token == address(0)) {\n // Send ETH\n (bool sent, ) = to.call{value: amount}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(token).safeTransfer(to, amount);\n }\n }\n}\n" + }, + "contracts/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IERC173} from '../interfaces/IERC173.sol';\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct TransientState {\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn != address(0)) {\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n TransientState memory t;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (msg.value == 0) {\n if (params.tokenIn == address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n } else {\n if (params.tokenIn != address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/DiamondMultiInit.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\n\ncontract DiamondMultiInit {\n // This function is provided in the third parameter of the `diamondCut` function.\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\n\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\n if (_addresses.length != _calldata.length) {\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\n }\n for (uint i; i < _addresses.length; i++) {\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/init/InitUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitUniV2Router {\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n if (!s.isInitialized) {\n s.isInitialized = true;\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\n s.weth = IWETH(s.uniswapV2router02.WETH());\n }\n\n s.uniswapV2Factory = uniswapV2Factory;\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Factory.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" + }, + "contracts/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/IKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\n\ninterface IKitty {\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\n\n function partnerWithdraw(address token) external;\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedValueAndTokenCombination();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/SifiDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from './libraries/LibDiamond.sol';\nimport {IDiamondCut} from './interfaces/IDiamondCut.sol';\nimport {IDiamondLoupe} from './interfaces/IDiamondLoupe.sol';\n\ncontract SifiDiamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), '');\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), 'Diamond: Function does not exist');\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n receive() external payable {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/arbitrum/solcInputs/df6263755b6a66e75866b356448256e7.json b/packages/hardhat/deployments/arbitrum/solcInputs/df6263755b6a66e75866b356448256e7.json new file mode 100644 index 00000000..958f2b3a --- /dev/null +++ b/packages/hardhat/deployments/arbitrum/solcInputs/df6263755b6a66e75866b356448256e7.json @@ -0,0 +1,119 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and `t.amount` will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\n * because only `t.token` can be moved by Stargate.\n *\n * This command must not run inside of a split.\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * `IStargateRouter.quoteLayerZeroFee`\n *\n * The value for `t.token` remains the same and is not chained.\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint8)\n * - dstPoolId (uint8)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n revert NativeTokenNotSupported();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // Max 5% slippage\n _minAmountLD: (t.amount * 95) / 100,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(t.paramRecipient),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error NativeTokenNotSupported();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/mainnet/Curve.json b/packages/hardhat/deployments/mainnet/Curve.json index 7817c490..7f27314c 100644 --- a/packages/hardhat/deployments/mainnet/Curve.json +++ b/packages/hardhat/deployments/mainnet/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x2C9300da6F29C8a58Be522AFf42731822393E5A8", + "address": "0xD9fd8268771eBF3701fBB28Ca7Cb8AEAbE0BAb4F", "abi": [ { "inputs": [], @@ -141,28 +141,28 @@ "type": "function" } ], - "transactionHash": "0x8847d6f51578fd9d670f570fc51ac2275e88ed6249568ebe0f93598561c3ef94", + "transactionHash": "0xabaab3b86ccbaaf4328add7a0e80540224c79cc515c1ef5685224e9b71c77ff4", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x2C9300da6F29C8a58Be522AFf42731822393E5A8", - "transactionIndex": 71, + "contractAddress": "0xD9fd8268771eBF3701fBB28Ca7Cb8AEAbE0BAb4F", + "transactionIndex": 44, "gasUsed": "1277871", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf55be052bc6bcb3ff8662e06d40d16f9070ecf1100c08e8916b476687f131f9f", - "transactionHash": "0x8847d6f51578fd9d670f570fc51ac2275e88ed6249568ebe0f93598561c3ef94", + "blockHash": "0xa364011370f352c6a3e50b4dd3ae649b58c3ee02619548703bf8b59474422e70", + "transactionHash": "0xabaab3b86ccbaaf4328add7a0e80540224c79cc515c1ef5685224e9b71c77ff4", "logs": [], - "blockNumber": 18181200, - "cumulativeGasUsed": "24543117", + "blockNumber": 18217289, + "cumulativeGasUsed": "4092621", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26a236ab658af7341bd585a6fd11474bb627ba050aca1c08532cd29c72d314c9\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x377723b233f7e22e77f9b0da81d8fb8f78d5adcdb6bb7817f06e602dea6f182e\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb8f29211d45827b00c6c594b8f0b68517a33881f55d8988a06d0721df488ce12\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x7439d7d6a66ec29616591dcfe8252bd92ec4852f58edcfb9b1e7102d1d43b74c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/DiamondCutFacet.json b/packages/hardhat/deployments/mainnet/DiamondCutFacet.json index c26fa6fd..934ae9ab 100644 --- a/packages/hardhat/deployments/mainnet/DiamondCutFacet.json +++ b/packages/hardhat/deployments/mainnet/DiamondCutFacet.json @@ -1,5 +1,5 @@ { - "address": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", + "address": "0x83Ba1c07459A31bBD59289e182B307FAc2445f08", "abi": [ { "inputs": [ @@ -100,28 +100,28 @@ "type": "function" } ], - "transactionHash": "0x2ec5b17aa233fe869a2faa59e7c1b72a01e9c8147f6a9b5ace221154df8ebdce", + "transactionHash": "0xc1ae3b5162c9d905f0bcbfbc46a5414a7872aa766b8aa32370fe48c936f1afec", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x56880c7B8eE5c4CF8e362bfa4e493B4b6d3245d3", - "transactionIndex": 141, + "contractAddress": "0x83Ba1c07459A31bBD59289e182B307FAc2445f08", + "transactionIndex": 65, "gasUsed": "1563324", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7d81859f04e92256def3d7cab895b9e759a835b101e27caddb421722c23fae8a", - "transactionHash": "0x2ec5b17aa233fe869a2faa59e7c1b72a01e9c8147f6a9b5ace221154df8ebdce", + "blockHash": "0xf5525703f47f7f5899b8e94bece316981c4b0024ada1c07e9c7e9022f3098336", + "transactionHash": "0xc1ae3b5162c9d905f0bcbfbc46a5414a7872aa766b8aa32370fe48c936f1afec", "logs": [], - "blockNumber": 18140496, - "cumulativeGasUsed": "18086508", + "blockNumber": 18217256, + "cumulativeGasUsed": "8005361", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x862ac209f7309608ba3e033d6f2e185d82936745ae9eff95d78681bd7c09799a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0xfb51534d56cfbfc884869f4c67b3b01fb3303a762418d796feabb78543d289ee\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/mainnet/DiamondLoupeFacet.json b/packages/hardhat/deployments/mainnet/DiamondLoupeFacet.json index 7b31b98f..91ddddec 100644 --- a/packages/hardhat/deployments/mainnet/DiamondLoupeFacet.json +++ b/packages/hardhat/deployments/mainnet/DiamondLoupeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", + "address": "0x5256c413F22Dafc7Db30531AD224Be948Ab12907", "abi": [ { "inputs": [ @@ -78,28 +78,28 @@ "type": "function" } ], - "transactionHash": "0xb7bae854b8e67e0a85762d897db788de564efb928c2b923b80438e807037fe57", + "transactionHash": "0x3d504bc63e3d7d4a505671eb5fd39fc4143a6b1f25aba7b33a4bd31585198617", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x352AfE52B0972d67148C01690cB90281fBF6bC35", - "transactionIndex": 121, + "contractAddress": "0x5256c413F22Dafc7Db30531AD224Be948Ab12907", + "transactionIndex": 56, "gasUsed": "480256", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf34c70a017c6e6c82bf789c046c426452e4cf5cb5b3e4a68bf3be9ea984507f4", - "transactionHash": "0xb7bae854b8e67e0a85762d897db788de564efb928c2b923b80438e807037fe57", + "blockHash": "0x5ebc905dbe60c3b2b71c39a9459493ff52b91830373cf262bda923c82392198e", + "transactionHash": "0x3d504bc63e3d7d4a505671eb5fd39fc4143a6b1f25aba7b33a4bd31585198617", "logs": [], - "blockNumber": 18140497, - "cumulativeGasUsed": "27491928", + "blockNumber": 18217258, + "cumulativeGasUsed": "5596433", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x912f2287b015cd1568157eb79d48033d8db3be846de4c50691d44ad5dc1a638b\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x5edfd8138efb21086b53df2028f755aae576b00a7193102cca00d14beb025475\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/mainnet/DiamondMultiInit.json b/packages/hardhat/deployments/mainnet/DiamondMultiInit.json index 96078627..0ddfb1d2 100644 --- a/packages/hardhat/deployments/mainnet/DiamondMultiInit.json +++ b/packages/hardhat/deployments/mainnet/DiamondMultiInit.json @@ -1,5 +1,5 @@ { - "address": "0xeC0E3045D85c0dd0763d8F0A88F964aE51d154e0", + "address": "0xd8B7cA69023C21BbA039Dd7e863515C6a7F205E1", "abi": [ { "inputs": [ @@ -52,28 +52,28 @@ "type": "function" } ], - "transactionHash": "0x8b9cf0304ac39e696aad41ea58adb0fde40c55fe1d82bc677e7cf16e22d94291", + "transactionHash": "0x0337b9f4993793695df7e81aed74abf2dd599526dba1dde3f3535587436e2be3", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xeC0E3045D85c0dd0763d8F0A88F964aE51d154e0", + "contractAddress": "0xd8B7cA69023C21BbA039Dd7e863515C6a7F205E1", "transactionIndex": 97, "gasUsed": "358464", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xccd6a4d088eb35280e627ddfeb3332a094dd5ca8f64a2d1afce4f55da6176ca8", - "transactionHash": "0x8b9cf0304ac39e696aad41ea58adb0fde40c55fe1d82bc677e7cf16e22d94291", + "blockHash": "0x9f7170ba4070decdb8dd8c0a1e690e2809f27590a9171559598fa5d11f10d4b0", + "transactionHash": "0x0337b9f4993793695df7e81aed74abf2dd599526dba1dde3f3535587436e2be3", "logs": [], - "blockNumber": 18140508, - "cumulativeGasUsed": "11332002", + "blockNumber": 18217295, + "cumulativeGasUsed": "14590545", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7039f6a07145a76f91a7f976a7f6af7fba83d559a3f895e6c425fe1fbd239fce\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8a6197389eba7856703a1fbabf7ecdd760678fcaf61be646731a14e4f88e80e9\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/InitLibWarp.json b/packages/hardhat/deployments/mainnet/InitLibWarp.json index c7ecb673..d72379aa 100644 --- a/packages/hardhat/deployments/mainnet/InitLibWarp.json +++ b/packages/hardhat/deployments/mainnet/InitLibWarp.json @@ -1,5 +1,5 @@ { - "address": "0x7E3EbEa12c8e52EB5e75D9DAeCb2676e5AF68517", + "address": "0xE629194E5f465Fe357ae6a2C92F663F9bdA1247b", "abi": [ { "inputs": [ @@ -12,6 +12,11 @@ "internalType": "address", "name": "permit2", "type": "address" + }, + { + "internalType": "address", + "name": "router", + "type": "address" } ], "name": "init", @@ -20,28 +25,28 @@ "type": "function" } ], - "transactionHash": "0x4131bbf9fe3ec2cebb1d16b25223b05f765146e784290c75d5fcf0dc16c463f3", + "transactionHash": "0xa0a75ff96ea85e5f76449283f012c54aad02d8a10924f3fd0091dd58f1f21e88", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x7E3EbEa12c8e52EB5e75D9DAeCb2676e5AF68517", - "transactionIndex": 64, - "gasUsed": "129825", + "contractAddress": "0xE629194E5f465Fe357ae6a2C92F663F9bdA1247b", + "transactionIndex": 74, + "gasUsed": "143701", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x88f7f97b2891c27a60efddb5477bed7ee5a16f09baf338635f2872396358016f", - "transactionHash": "0x4131bbf9fe3ec2cebb1d16b25223b05f765146e784290c75d5fcf0dc16c463f3", + "blockHash": "0x3623b3ff1e4a1157f07c8a77d3be75874380bff968f3b73d45151106d935e686", + "transactionHash": "0xa0a75ff96ea85e5f76449283f012c54aad02d8a10924f3fd0091dd58f1f21e88", "logs": [], - "blockNumber": 18181202, - "cumulativeGasUsed": "9310981", + "blockNumber": 18217293, + "cumulativeGasUsed": "10887528", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0x8e3d3c6cee0d946dec6ad0cb6ff3f9c902771d51868ec082a9aa440bd84685ad\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610163806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2, address router) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n s.stargateRouter = IStargateRouter(router);\\n }\\n}\\n\",\"keccak256\":\"0xd9e7e1bf8fc13c1490d02df612a04e30f3ad189728f67888d4ab6ad884e30d43\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/InitUniV2Router.json b/packages/hardhat/deployments/mainnet/InitUniV2Router.json index 4dc8e010..8a522d3f 100644 --- a/packages/hardhat/deployments/mainnet/InitUniV2Router.json +++ b/packages/hardhat/deployments/mainnet/InitUniV2Router.json @@ -1,5 +1,5 @@ { - "address": "0x98b48b988d9D99e17B02180845ef5937595551EB", + "address": "0x7D03B60D0a8B854d688DcbEE6a08A8f7A80c0a1e", "abi": [ { "inputs": [ @@ -25,28 +25,28 @@ "type": "function" } ], - "transactionHash": "0xa61c592960110f1b6ad67589afd92b7f0ca38b77fd6664e91548700fe8a8e598", + "transactionHash": "0xe8f3a1550f05edc8e800380eb5cfc15a879e0ba4745d705cb80dd6b3c5893808", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x98b48b988d9D99e17B02180845ef5937595551EB", - "transactionIndex": 72, + "contractAddress": "0x7D03B60D0a8B854d688DcbEE6a08A8f7A80c0a1e", + "transactionIndex": 77, "gasUsed": "204425", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd487d91e9ad128f7a1ddc03ba4fbbb110b10b4106674dcaf6af35bfdd2a7d7d9", - "transactionHash": "0xa61c592960110f1b6ad67589afd92b7f0ca38b77fd6664e91548700fe8a8e598", + "blockHash": "0xdcc3b5459bf2d7c24ef424668af8636f852610afab608de06cdffa7aa7e7eee8", + "transactionHash": "0xe8f3a1550f05edc8e800380eb5cfc15a879e0ba4745d705cb80dd6b3c5893808", "logs": [], - "blockNumber": 18189388, - "cumulativeGasUsed": "6702212", + "blockNumber": 18217294, + "cumulativeGasUsed": "8266198", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 7, - "solcInputHash": "7ec6f1f3e7a5d1b83d66ab59508a5e49", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"uniswapV2Router02\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"uniswapV2Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitUniV2Router.sol\":\"InitUniV2Router\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\ninterface IUniswapV2Router01 {\\n function factory() external pure returns (address);\\n function WETH() external pure returns (address);\\n\\n function addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB, uint liquidity);\\n function addLiquidityETH(\\n address token,\\n uint amountTokenDesired,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\\n function removeLiquidity(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETH(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountToken, uint amountETH);\\n function removeLiquidityWithPermit(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETHWithPermit(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountToken, uint amountETH);\\n function swapExactTokensForTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapTokensForExactTokens(\\n uint amountOut,\\n uint amountInMax,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n\\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\\n}\\n\",\"keccak256\":\"0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\nimport './IUniswapV2Router01.sol';\\n\\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\\n function removeLiquidityETHSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountETH);\\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountETH);\\n\\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external payable;\\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n}\\n\",\"keccak256\":\"0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitUniV2Router {\\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n if (!s.isInitialized) {\\n s.isInitialized = true;\\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\\n s.weth = IWETH(s.uniswapV2router02.WETH());\\n }\\n\\n s.uniswapV2Factory = uniswapV2Factory;\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0x1ae31d1f04a9c6f1af0d3ce5de327e2a2b6a825ce92017f7bbf3fb9156ee8b9a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibUniV2Router {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\\n\\n struct DiamondStorage {\\n bool isInitialized;\\n IWETH weth;\\n IUniswapV2Router02 uniswapV2router02;\\n address uniswapV2Factory;\\n IPermit2 permit2;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n\\n assembly {\\n s.slot := position\\n }\\n }\\n\\n // calculates the CREATE2 address for a pair without making any external calls\\n // NOTE: Modified to work with newer Solidity\\n function pairFor(\\n address factory,\\n address tokenA,\\n address tokenB\\n ) internal pure returns (address pair) {\\n if (tokenA > tokenB) {\\n (tokenA, tokenB) = (tokenB, tokenA);\\n }\\n\\n pair = address(\\n uint160(\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n hex'ff',\\n factory,\\n keccak256(abi.encodePacked(tokenA, tokenB)),\\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\\n )\\n )\\n )\\n )\\n );\\n }\\n\\n function getPairsAndAmountsFromPath(\\n address factory,\\n uint256 amountIn,\\n address[] memory path\\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\\n uint256 pathLengthMinusOne = path.length - 1;\\n\\n pairs = new address[](pathLengthMinusOne);\\n amounts = new uint256[](path.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < pathLengthMinusOne; ) {\\n address token0 = path[index];\\n address token1 = path[index + 1];\\n\\n pairs[index] = pairFor(factory, token0, token1);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\\n .getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3ea99261b7a2f5b685deff7e4e43851b25982abb8361c58cb54ca1d083eb89ce\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506102c0806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b61004361003e36600461021b565b610045565b005b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c805460ff1661019d5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558101805473ffffffffffffffffffffffffffffffffffffffff86167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155604080517fad5c4648000000000000000000000000000000000000000000000000000000008152905163ad5c4648916004808201926020929091908290030181865afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610266565b815473ffffffffffffffffffffffffffffffffffffffff91909116610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9091161781555b60028101805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556003909101805492909316911617905550565b73ffffffffffffffffffffffffffffffffffffffff8116811461021857600080fd5b50565b60008060006060848603121561023057600080fd5b833561023b816101f6565b9250602084013561024b816101f6565b9150604084013561025b816101f6565b809150509250925092565b60006020828403121561027857600080fd5b8151610283816101f6565b939250505056fea2646970667358221220c71cd8ae2f8a0a8ba7af37332e53ad64c115c7be9d6d842096693159eef1975364736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b61004361003e36600461021b565b610045565b005b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c805460ff1661019d5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558101805473ffffffffffffffffffffffffffffffffffffffff86167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155604080517fad5c4648000000000000000000000000000000000000000000000000000000008152905163ad5c4648916004808201926020929091908290030181865afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610266565b815473ffffffffffffffffffffffffffffffffffffffff91909116610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9091161781555b60028101805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556003909101805492909316911617905550565b73ffffffffffffffffffffffffffffffffffffffff8116811461021857600080fd5b50565b60008060006060848603121561023057600080fd5b833561023b816101f6565b9250602084013561024b816101f6565b9150604084013561025b816101f6565b809150509250925092565b60006020828403121561027857600080fd5b8151610283816101f6565b939250505056fea2646970667358221220c71cd8ae2f8a0a8ba7af37332e53ad64c115c7be9d6d842096693159eef1975364736f6c63430008130033", + "numDeployments": 8, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"uniswapV2Router02\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"uniswapV2Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitUniV2Router.sol\":\"InitUniV2Router\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\ninterface IUniswapV2Router01 {\\n function factory() external pure returns (address);\\n function WETH() external pure returns (address);\\n\\n function addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB, uint liquidity);\\n function addLiquidityETH(\\n address token,\\n uint amountTokenDesired,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\\n function removeLiquidity(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETH(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountToken, uint amountETH);\\n function removeLiquidityWithPermit(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETHWithPermit(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountToken, uint amountETH);\\n function swapExactTokensForTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapTokensForExactTokens(\\n uint amountOut,\\n uint amountInMax,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n\\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\\n}\\n\",\"keccak256\":\"0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\nimport './IUniswapV2Router01.sol';\\n\\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\\n function removeLiquidityETHSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountETH);\\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountETH);\\n\\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external payable;\\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n}\\n\",\"keccak256\":\"0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitUniV2Router {\\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n if (!s.isInitialized) {\\n s.isInitialized = true;\\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\\n s.weth = IWETH(s.uniswapV2router02.WETH());\\n }\\n\\n s.uniswapV2Factory = uniswapV2Factory;\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0xc2da2260237e52da4935bb570672a186c93db369ed7d01d109a358b2162c3cef\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibUniV2Router {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\\n\\n struct DiamondStorage {\\n bool isInitialized;\\n IWETH weth;\\n IUniswapV2Router02 uniswapV2router02;\\n address uniswapV2Factory;\\n IPermit2 permit2;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n\\n assembly {\\n s.slot := position\\n }\\n }\\n\\n // calculates the CREATE2 address for a pair without making any external calls\\n // NOTE: Modified to work with newer Solidity\\n function pairFor(\\n address factory,\\n address tokenA,\\n address tokenB\\n ) internal pure returns (address pair) {\\n if (tokenA > tokenB) {\\n (tokenA, tokenB) = (tokenB, tokenA);\\n }\\n\\n pair = address(\\n uint160(\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n hex'ff',\\n factory,\\n keccak256(abi.encodePacked(tokenA, tokenB)),\\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\\n )\\n )\\n )\\n )\\n );\\n }\\n\\n function getPairsAndAmountsFromPath(\\n address factory,\\n uint256 amountIn,\\n address[] memory path\\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\\n uint256 pathLengthMinusOne = path.length - 1;\\n\\n pairs = new address[](pathLengthMinusOne);\\n amounts = new uint256[](path.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < pathLengthMinusOne; ) {\\n address token0 = path[index];\\n address token1 = path[index + 1];\\n\\n pairs[index] = pairFor(factory, token0, token1);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\\n .getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4361775eb2d3cf877967ca8f4920daa676dea87c73bce2e55ca4208d1d2dd78b\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506102c0806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b61004361003e36600461021b565b610045565b005b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c805460ff1661019d5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558101805473ffffffffffffffffffffffffffffffffffffffff86167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155604080517fad5c4648000000000000000000000000000000000000000000000000000000008152905163ad5c4648916004808201926020929091908290030181865afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610266565b815473ffffffffffffffffffffffffffffffffffffffff91909116610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9091161781555b60028101805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556003909101805492909316911617905550565b73ffffffffffffffffffffffffffffffffffffffff8116811461021857600080fd5b50565b60008060006060848603121561023057600080fd5b833561023b816101f6565b9250602084013561024b816101f6565b9150604084013561025b816101f6565b809150509250925092565b60006020828403121561027857600080fd5b8151610283816101f6565b939250505056fea26469706673582212205565cc98cb39f773e1a1481c3e6e3923501502c75b72faaa8f4c27ba7ef9730164736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b61004361003e36600461021b565b610045565b005b7fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c805460ff1661019d5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558101805473ffffffffffffffffffffffffffffffffffffffff86167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155604080517fad5c4648000000000000000000000000000000000000000000000000000000008152905163ad5c4648916004808201926020929091908290030181865afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610266565b815473ffffffffffffffffffffffffffffffffffffffff91909116610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9091161781555b60028101805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556003909101805492909316911617905550565b73ffffffffffffffffffffffffffffffffffffffff8116811461021857600080fd5b50565b60008060006060848603121561023057600080fd5b833561023b816101f6565b9250602084013561024b816101f6565b9150604084013561025b816101f6565b809150509250925092565b60006020828403121561027857600080fd5b8151610283816101f6565b939250505056fea26469706673582212205565cc98cb39f773e1a1481c3e6e3923501502c75b72faaa8f4c27ba7ef9730164736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/KittyFacet.json b/packages/hardhat/deployments/mainnet/KittyFacet.json index f9db42cf..eec84e70 100644 --- a/packages/hardhat/deployments/mainnet/KittyFacet.json +++ b/packages/hardhat/deployments/mainnet/KittyFacet.json @@ -1,5 +1,5 @@ { - "address": "0x1C3291D62DAcC0d75b538a3D82b539bA593a7AeB", + "address": "0x4a8e2c37D37b7bA6814762b2D6563821F4da37ad", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0x362c140b3e76f410b60d07fd2eb8c23c248cc5c2a2e52815cd1c3dd4c152e9d0", + "transactionHash": "0x0030ba05c0e94e4a55a216458c17400616017a41e539a2895763157b664623f2", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x1C3291D62DAcC0d75b538a3D82b539bA593a7AeB", - "transactionIndex": 54, + "contractAddress": "0x4a8e2c37D37b7bA6814762b2D6563821F4da37ad", + "transactionIndex": 102, "gasUsed": "825445", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x42faaa29d3eba1b492e5df9d0ee88385bfcdf5df3714c712589055d55994af2a", - "transactionHash": "0x362c140b3e76f410b60d07fd2eb8c23c248cc5c2a2e52815cd1c3dd4c152e9d0", + "blockHash": "0xbb4e1e11b1a8ebc3cc0c5126b47334d1035ae7e6a42739a8129d88eba6e34969", + "transactionHash": "0x0030ba05c0e94e4a55a216458c17400616017a41e539a2895763157b664623f2", "logs": [], - "blockNumber": 18140499, - "cumulativeGasUsed": "6606069", + "blockNumber": 18217268, + "cumulativeGasUsed": "24104196", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b2dbdcc0b6941fae124c7dae9af5f1726bb6c522b1bb92b1dede393f5927230\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0xcf24bb7018a505bbb0f35146f9793f6ef407ce11a998817aff570a66e7848b98\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0xa4b787bb171f2fd5cba3310a8cee7eee32e4ab06f5902a6fcd62273c551115ed\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3abf20697535d8feceedd82cbde3105a9e6a6c6ddfc75532a588bca369ab520d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0x6cf80a254d66f174fc82fdc474aea1b71dad36e3a6cf0e2353e2298e04041ce2\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0x9b80854a259f0f4fe4e72968297f1d28afe40d9c62a6d59df007568be79f8b02\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/OwnershipFacet.json b/packages/hardhat/deployments/mainnet/OwnershipFacet.json index 965fc46a..4aa341d9 100644 --- a/packages/hardhat/deployments/mainnet/OwnershipFacet.json +++ b/packages/hardhat/deployments/mainnet/OwnershipFacet.json @@ -1,5 +1,5 @@ { - "address": "0xf1f10E1c70aa70b737147205543E7F7f04B7bD87", + "address": "0x2DE9E2B8A7C9105FDb864881a4F4c73Eb190927F", "abi": [ { "anonymous": false, @@ -47,28 +47,28 @@ "type": "function" } ], - "transactionHash": "0xe45c42763d85edc8c85f2a18c41f88b7fdb1d5679a99ea25b3b1064157ee5676", + "transactionHash": "0x86eae6b903fdf7e78c2149321365c0866fbbe2ef18d5625db9543415da93ac6e", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xf1f10E1c70aa70b737147205543E7F7f04B7bD87", - "transactionIndex": 99, + "contractAddress": "0x2DE9E2B8A7C9105FDb864881a4F4c73Eb190927F", + "transactionIndex": 75, "gasUsed": "209282", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5ea3f9cefa0fd998e90bb23680e0c43e4d67e68b4b208704cebc3a5cc0f87b3f", - "transactionHash": "0xe45c42763d85edc8c85f2a18c41f88b7fdb1d5679a99ea25b3b1064157ee5676", + "blockHash": "0x9fc3647e4a1f53012266e777279ecfc5ab8cbb7ddd402a3706decac116dc616a", + "transactionHash": "0x86eae6b903fdf7e78c2149321365c0866fbbe2ef18d5625db9543415da93ac6e", "logs": [], - "blockNumber": 18140498, - "cumulativeGasUsed": "13098205", + "blockNumber": 18217263, + "cumulativeGasUsed": "5824953", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0x2836ab3ca2aebaaffbafed73912c31012d34b0a20860394fd7050199401de018\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0xd14213dfd60c9476041ad22fcb96d4d81cda561979c24befa9de88220dae51d2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", "devdoc": { "events": { "OwnershipTransferred(address,address)": { diff --git a/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json b/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json index 04c5b3d0..1daca942 100644 --- a/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/mainnet/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x65F1F2Bf39c3d72a8801e67372147D3BFC997f41", + "address": "0x58008F004bC571d610643E2979621884E01A3FBf", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0x84195f000a95a457887a1b2f685aec98fd95d0bf3b778a093cacb11e2da46fec", + "transactionHash": "0x9256077530c264ac4051739981a7bf08efc4f7e6d0bd27da6f646011fe1bb545", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x65F1F2Bf39c3d72a8801e67372147D3BFC997f41", - "transactionIndex": 153, - "gasUsed": "2057031", + "contractAddress": "0x58008F004bC571d610643E2979621884E01A3FBf", + "transactionIndex": 87, + "gasUsed": "2057019", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa155b70c29abef9703901813e72ef700c56a27a0f4f9d915eb130a98274ef813", - "transactionHash": "0x84195f000a95a457887a1b2f685aec98fd95d0bf3b778a093cacb11e2da46fec", + "blockHash": "0x6689ad127fdb958279e359d7d2451949836d4b1c003ed97f3fb1fd9b64c95bc2", + "transactionHash": "0x9256077530c264ac4051739981a7bf08efc4f7e6d0bd27da6f646011fe1bb545", "logs": [], - "blockNumber": 18181196, - "cumulativeGasUsed": "14146919", + "blockNumber": 18217270, + "cumulativeGasUsed": "10298143", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56e7341e6a317f670cc3df2ee1e18b3a47c8e11f302db67b787aba91007d2280\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xcf11728bd04fa6c509bfa1093d6e6f9490a1b2fb41a94144d13d0c0abe3db24a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xea45669f18797f167c70a3fc6ee194fa38fea7a14d310045083d2b64bb88397d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x8dec0c768b0e3875e1e59d241435bcdf88de646aa674ad20c26204d166d6acc9\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json b/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json index be53c5f7..0b803969 100644 --- a/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json +++ b/packages/hardhat/deployments/mainnet/UniV2RouterFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd0D1EDc96c8492fd8A4D03300Bc05D3cB799ffa0", + "address": "0x9c115669E870Fe4B3B982D68932Fd083a520C10e", "abi": [ { "inputs": [], @@ -199,28 +199,28 @@ "type": "function" } ], - "transactionHash": "0x58ff6e22da9dea635dfa488c988010e58743ef5326bb479dbe5f17e63790ebd4", + "transactionHash": "0xe475d1aa5a70bd68549ebdae959bb8e90be550100c06ffc06cfcef4c0f62a2f5", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd0D1EDc96c8492fd8A4D03300Bc05D3cB799ffa0", - "transactionIndex": 78, + "contractAddress": "0x9c115669E870Fe4B3B982D68932Fd083a520C10e", + "transactionIndex": 69, "gasUsed": "2001494", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6aa8b24b33696bc60f9c3ddd93065db24b054d56f4f7d554eaabc780fcf9f047", - "transactionHash": "0x58ff6e22da9dea635dfa488c988010e58743ef5326bb479dbe5f17e63790ebd4", + "blockHash": "0xced620564669b0f92448def0c3202f17dc331cb52ebef5b6f35b438d3edc465a", + "transactionHash": "0xe475d1aa5a70bd68549ebdae959bb8e90be550100c06ffc06cfcef4c0f62a2f5", "logs": [], - "blockNumber": 18189385, - "cumulativeGasUsed": "10033096", + "blockNumber": 18217291, + "cumulativeGasUsed": "11372101", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 10, - "solcInputHash": "ef2a191fbb0a0d9b0d41d87bc112e31a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmountOut\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippage\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"path\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Router.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2ExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippage\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"}],\"internalType\":\"struct IUniV2Router.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2ExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2RouterFacet.sol\":\"UniV2RouterFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\ninterface IUniswapV2Router01 {\\n function factory() external pure returns (address);\\n function WETH() external pure returns (address);\\n\\n function addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB, uint liquidity);\\n function addLiquidityETH(\\n address token,\\n uint amountTokenDesired,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\\n function removeLiquidity(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETH(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountToken, uint amountETH);\\n function removeLiquidityWithPermit(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETHWithPermit(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountToken, uint amountETH);\\n function swapExactTokensForTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapTokensForExactTokens(\\n uint amountOut,\\n uint amountInMax,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n\\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\\n}\\n\",\"keccak256\":\"0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\nimport './IUniswapV2Router01.sol';\\n\\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\\n function removeLiquidityETHSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountETH);\\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountETH);\\n\\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external payable;\\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n}\\n\",\"keccak256\":\"0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2RouterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract UniV2RouterFacet is IUniV2Router {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2ExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert Errors.DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountOut =\\n ((params.amountIn * 997) * reserveOut) /\\n ((reserveIn * 1000) + (params.amountIn * 997));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert Errors.InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert Errors.IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(pair).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert Errors.ZeroAmountOut();\\n }\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2ExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert Errors.DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n uint256 pathLengthMinusOne = params.path.length - 1;\\n bool isFromEth = params.path[0] == address(0);\\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\\n\\n if (isFromEth) {\\n params.path[0] = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.path[pathLengthMinusOne] = address(s.weth);\\n }\\n\\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\\n s.uniswapV2Factory,\\n params.amountIn,\\n params.path\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert Errors.InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert Errors.IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.path[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\\n }\\n\\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < pathLengthMinusOne; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(pairs[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n ++index;\\n }\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.path[pathLengthMinusOne],\\n params.feeBps,\\n params.amountOut,\\n amounts[pathLengthMinusOne]\\n );\\n\\n if (amountOut == 0) {\\n revert Errors.ZeroAmountOut();\\n }\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb9d4e1352deef0f17e0d96476050a94477f829d8fc677e994bbcf8d00c1c4ec0\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Router {\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippage;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] path;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippage;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n }\\n\\n function uniswapV2ExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2ExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xb512b47498293d732a74f0525e88fd1126d9fffc8c0a5352efd4cdf23d6622a8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0xa4b787bb171f2fd5cba3310a8cee7eee32e4ab06f5902a6fcd62273c551115ed\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibUniV2Router {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\\n\\n struct DiamondStorage {\\n bool isInitialized;\\n IWETH weth;\\n IUniswapV2Router02 uniswapV2router02;\\n address uniswapV2Factory;\\n IPermit2 permit2;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n\\n assembly {\\n s.slot := position\\n }\\n }\\n\\n // calculates the CREATE2 address for a pair without making any external calls\\n // NOTE: Modified to work with newer Solidity\\n function pairFor(\\n address factory,\\n address tokenA,\\n address tokenB\\n ) internal pure returns (address pair) {\\n if (tokenA > tokenB) {\\n (tokenA, tokenB) = (tokenB, tokenA);\\n }\\n\\n pair = address(\\n uint160(\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n hex'ff',\\n factory,\\n keccak256(abi.encodePacked(tokenA, tokenB)),\\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\\n )\\n )\\n )\\n )\\n );\\n }\\n\\n function getPairsAndAmountsFromPath(\\n address factory,\\n uint256 amountIn,\\n address[] memory path\\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\\n uint256 pathLengthMinusOne = path.length - 1;\\n\\n pairs = new address[](pathLengthMinusOne);\\n amounts = new uint256[](path.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < pathLengthMinusOne; ) {\\n address token0 = path[index];\\n address token1 = path[index + 1];\\n\\n pairs[index] = pairFor(factory, token0, token1);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\\n .getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3ea99261b7a2f5b685deff7e4e43851b25982abb8361c58cb54ca1d083eb89ce\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50612369806100206000396000f3fe6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611dde565b610066565b60405190815260200160405180910390f35b610041610061366004611eda565b610a8c565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e590600190611fe5565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015160008151811061011757610117611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061016757610167611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061024657610246611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff9092169161122e565b915091506102ca89602001518a606001516114d3565b81600183516102d99190611fe5565b815181106102e9576102e9611ff8565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b50505050506104558260008151811061040457610404611ff8565b60200260200101518a600001518b60e0015160008151811061042857610428611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c8611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e9190612027565b6040518563ffffffff1660e01b815260040161058d9493929190612093565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f8611ff8565b60200260200101518c600001518d60e0015160008151811061061c5761061c611ff8565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c1826001612155565b905060008b60e0015182815181106106db576106db611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e00151516107529190611fe5565b841061075e5730610779565b85838151811061077057610770611ff8565b60200260200101515b905085848151811061078d5761078d611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c7611ff8565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f5611ff8565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f48960c001518a60e0015187815181106108c3576108c3611ff8565b60200260200101518b608001518c60200151858a815181106108e7576108e7611ff8565b6020026020010151611595565b965086600003610930576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a615785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a557600080fd5b505af11580156109b9573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1b576040519150601f19603f3d011682016040523d82523d6000602084013e610a20565b606091505b5050905080610a5b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a80565b610a808960400151888b60e00151888151811061042857610428611ff8565b50505050505092915050565b60008260a0015165ffffffffffff16421115610ad4576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610b46578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610b7057825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610ba59273ffffffffffffffffffffffffffffffffffffffff90911691611656565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610c7d57905b88516103e58082026103e88502019183020281610c9c57610c9c6121d6565b049650610cb189602001518a606001516114d3565b871015610cea576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ddd5788513414610d2a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b50508b5160e08d0151610dd8945073ffffffffffffffffffffffffffffffffffffffff169250869150611503565b610f5e565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610e69908d018d612027565b6040518563ffffffff1660e01b8152600401610e889493929190612093565b600060405180830381600087803b158015610ea257600080fd5b505af1158015610eb6573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff1610610fa3576000610fa6565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610fcf5789610fd2565b60005b83610fde576000610fe0565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506110808a60c001518b61010001518c608001518d602001518c611595565b9750876000036110bc576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156111ed5786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561113157600080fd5b505af1158015611145573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d80600081146111a7576040519150601f19603f3d011682016040523d82523d6000602084013e6111ac565b606091505b50509050806111e7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611221565b6112218a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b5050505050505092915050565b6060806000600184516112419190611fe5565b90508067ffffffffffffffff81111561125c5761125c611c43565b604051908082528060200260200182016040528015611285578160200160208202803683370190505b509250835167ffffffffffffffff8111156112a2576112a2611c43565b6040519080825280602002602001820160405280156112cb578160200160208202803683370190505b50915084826000815181106112e2576112e2611ff8565b60200260200101818152505060005b818110156114c957600085828151811061130d5761130d611ff8565b602002602001015190506000868360016113279190612155565b8151811061133757611337611ff8565b6020026020010151905061134c898383611656565b86848151811061135e5761135e611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806113a68b8585611656565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561146f57905b896103e502826103e80201818b6103e502028161148e5761148e6121d6565b049950898761149e876001612155565b815181106114ae576114ae611ff8565b60209081029190910101525050600190920191506112f19050565b5050935093915050565b60006127106114e28382612205565b6114f09061ffff1685612227565b6114fa919061223e565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115909084906117af565b505050565b60006107d061ffff851611156115e0576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156115f2575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561162c576064603284020461162f565b60005b9050808303838214611647576116478a8a84846118be565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611690579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016117719291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b6000611811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119c39092919063ffffffff16565b90508051600014806118325750808060200190518101906118329190612279565b611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016115d7565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff84161561192e5773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061192c90856119da565b505b61193881866119da565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119d284846000856119fc565b949350505050565b60006114fa8373ffffffffffffffffffffffffffffffffffffffff8416611b15565b606082471015611a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016115d7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab791906122c6565b60006040518083038185875af1925050503d8060008114611af4576040519150601f19603f3d011682016040523d82523d6000602084013e611af9565b606091505b5091509150611b0a87838387611b64565b979650505050505050565b6000818152600183016020526040812054611b5c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114fd565b5060006114fd565b60608315611bfa578251600003611bf35773ffffffffffffffffffffffffffffffffffffffff85163b611bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115d7565b50816119d2565b6119d28383815115611c0f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d791906122e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611c9657611c96611c43565b60405290565b604051610120810167ffffffffffffffff81118282101715611c9657611c96611c43565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ce457600080fd5b919050565b803561ffff81168114611ce457600080fd5b803565ffffffffffff81168114611ce457600080fd5b600082601f830112611d2257600080fd5b8135602067ffffffffffffffff80831115611d3f57611d3f611c43565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611d8257611d82611c43565b604052938452858101830193838101925087851115611da057600080fd5b83870191505b84821015611b0a57611db782611cc0565b83529183019190830190611da6565b600060408284031215611dd857600080fd5b50919050565b60008060408385031215611df157600080fd5b823567ffffffffffffffff80821115611e0957600080fd5b908401906101008287031215611e1e57600080fd5b611e26611c72565b8235815260208301356020820152611e4060408401611cc0565b6040820152611e5160608401611ce9565b6060820152611e6260808401611ce9565b6080820152611e7360a08401611cfb565b60a0820152611e8460c08401611cc0565b60c082015260e083013582811115611e9b57600080fd5b611ea788828601611d11565b60e08301525093506020850135915080821115611ec357600080fd5b50611ed085828601611dc6565b9150509250929050565b600080828403610140811215611eef57600080fd5b61012080821215611eff57600080fd5b611f07611c9c565b91508435825260208501356020830152611f2360408601611cc0565b6040830152611f3460608601611ce9565b6060830152611f4560808601611ce9565b6080830152611f5660a08601611cfb565b60a0830152611f6760c08601611cc0565b60c0830152611f7860e08601611cc0565b60e0830152610100611f8b818701611cc0565b9083015290925083013567ffffffffffffffff811115611faa57600080fd5b611ed085828601611dc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156114fd576114fd611fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b60200191503681900382131561208c57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b808201808211156114fd576114fd611fb6565b80516dffffffffffffffffffffffffffff81168114611ce457600080fd5b60008060006060848603121561219b57600080fd5b6121a484612168565b92506121b260208501612168565b9150604084015163ffffffff811681146121cb57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff82811682821603908082111561222057612220611fb6565b5092915050565b80820281158282048414176114fd576114fd611fb6565b600082612274577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561228b57600080fd5b8151801515811461229b57600080fd5b9392505050565b60005b838110156122bd5781810151838201526020016122a5565b50506000910152565b600082516122d88184602087016122a2565b9190910192915050565b60208152600082518060208401526123018160408501602087016122a2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122099c4fec836f01952667913142136ee80fb4dcb36d3f71f5f3aecc4c5a2a2cf4064736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611dde565b610066565b60405190815260200160405180910390f35b610041610061366004611eda565b610a8c565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e590600190611fe5565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015160008151811061011757610117611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061016757610167611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061024657610246611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff9092169161122e565b915091506102ca89602001518a606001516114d3565b81600183516102d99190611fe5565b815181106102e9576102e9611ff8565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b50505050506104558260008151811061040457610404611ff8565b60200260200101518a600001518b60e0015160008151811061042857610428611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c8611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e9190612027565b6040518563ffffffff1660e01b815260040161058d9493929190612093565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f8611ff8565b60200260200101518c600001518d60e0015160008151811061061c5761061c611ff8565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c1826001612155565b905060008b60e0015182815181106106db576106db611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e00151516107529190611fe5565b841061075e5730610779565b85838151811061077057610770611ff8565b60200260200101515b905085848151811061078d5761078d611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c7611ff8565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f5611ff8565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f48960c001518a60e0015187815181106108c3576108c3611ff8565b60200260200101518b608001518c60200151858a815181106108e7576108e7611ff8565b6020026020010151611595565b965086600003610930576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a615785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a557600080fd5b505af11580156109b9573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1b576040519150601f19603f3d011682016040523d82523d6000602084013e610a20565b606091505b5050905080610a5b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a80565b610a808960400151888b60e00151888151811061042857610428611ff8565b50505050505092915050565b60008260a0015165ffffffffffff16421115610ad4576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610b46578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610b7057825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610ba59273ffffffffffffffffffffffffffffffffffffffff90911691611656565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610c7d57905b88516103e58082026103e88502019183020281610c9c57610c9c6121d6565b049650610cb189602001518a606001516114d3565b871015610cea576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ddd5788513414610d2a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b50508b5160e08d0151610dd8945073ffffffffffffffffffffffffffffffffffffffff169250869150611503565b610f5e565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610e69908d018d612027565b6040518563ffffffff1660e01b8152600401610e889493929190612093565b600060405180830381600087803b158015610ea257600080fd5b505af1158015610eb6573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff1610610fa3576000610fa6565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610fcf5789610fd2565b60005b83610fde576000610fe0565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506110808a60c001518b61010001518c608001518d602001518c611595565b9750876000036110bc576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156111ed5786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561113157600080fd5b505af1158015611145573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d80600081146111a7576040519150601f19603f3d011682016040523d82523d6000602084013e6111ac565b606091505b50509050806111e7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611221565b6112218a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b5050505050505092915050565b6060806000600184516112419190611fe5565b90508067ffffffffffffffff81111561125c5761125c611c43565b604051908082528060200260200182016040528015611285578160200160208202803683370190505b509250835167ffffffffffffffff8111156112a2576112a2611c43565b6040519080825280602002602001820160405280156112cb578160200160208202803683370190505b50915084826000815181106112e2576112e2611ff8565b60200260200101818152505060005b818110156114c957600085828151811061130d5761130d611ff8565b602002602001015190506000868360016113279190612155565b8151811061133757611337611ff8565b6020026020010151905061134c898383611656565b86848151811061135e5761135e611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806113a68b8585611656565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561146f57905b896103e502826103e80201818b6103e502028161148e5761148e6121d6565b049950898761149e876001612155565b815181106114ae576114ae611ff8565b60209081029190910101525050600190920191506112f19050565b5050935093915050565b60006127106114e28382612205565b6114f09061ffff1685612227565b6114fa919061223e565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115909084906117af565b505050565b60006107d061ffff851611156115e0576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156115f2575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561162c576064603284020461162f565b60005b9050808303838214611647576116478a8a84846118be565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611690579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016117719291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b6000611811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119c39092919063ffffffff16565b90508051600014806118325750808060200190518101906118329190612279565b611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016115d7565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff84161561192e5773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061192c90856119da565b505b61193881866119da565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119d284846000856119fc565b949350505050565b60006114fa8373ffffffffffffffffffffffffffffffffffffffff8416611b15565b606082471015611a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016115d7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab791906122c6565b60006040518083038185875af1925050503d8060008114611af4576040519150601f19603f3d011682016040523d82523d6000602084013e611af9565b606091505b5091509150611b0a87838387611b64565b979650505050505050565b6000818152600183016020526040812054611b5c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114fd565b5060006114fd565b60608315611bfa578251600003611bf35773ffffffffffffffffffffffffffffffffffffffff85163b611bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115d7565b50816119d2565b6119d28383815115611c0f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d791906122e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611c9657611c96611c43565b60405290565b604051610120810167ffffffffffffffff81118282101715611c9657611c96611c43565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ce457600080fd5b919050565b803561ffff81168114611ce457600080fd5b803565ffffffffffff81168114611ce457600080fd5b600082601f830112611d2257600080fd5b8135602067ffffffffffffffff80831115611d3f57611d3f611c43565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611d8257611d82611c43565b604052938452858101830193838101925087851115611da057600080fd5b83870191505b84821015611b0a57611db782611cc0565b83529183019190830190611da6565b600060408284031215611dd857600080fd5b50919050565b60008060408385031215611df157600080fd5b823567ffffffffffffffff80821115611e0957600080fd5b908401906101008287031215611e1e57600080fd5b611e26611c72565b8235815260208301356020820152611e4060408401611cc0565b6040820152611e5160608401611ce9565b6060820152611e6260808401611ce9565b6080820152611e7360a08401611cfb565b60a0820152611e8460c08401611cc0565b60c082015260e083013582811115611e9b57600080fd5b611ea788828601611d11565b60e08301525093506020850135915080821115611ec357600080fd5b50611ed085828601611dc6565b9150509250929050565b600080828403610140811215611eef57600080fd5b61012080821215611eff57600080fd5b611f07611c9c565b91508435825260208501356020830152611f2360408601611cc0565b6040830152611f3460608601611ce9565b6060830152611f4560808601611ce9565b6080830152611f5660a08601611cfb565b60a0830152611f6760c08601611cc0565b60c0830152611f7860e08601611cc0565b60e0830152610100611f8b818701611cc0565b9083015290925083013567ffffffffffffffff811115611faa57600080fd5b611ed085828601611dc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156114fd576114fd611fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b60200191503681900382131561208c57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b808201808211156114fd576114fd611fb6565b80516dffffffffffffffffffffffffffff81168114611ce457600080fd5b60008060006060848603121561219b57600080fd5b6121a484612168565b92506121b260208501612168565b9150604084015163ffffffff811681146121cb57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff82811682821603908082111561222057612220611fb6565b5092915050565b80820281158282048414176114fd576114fd611fb6565b600082612274577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561228b57600080fd5b8151801515811461229b57600080fd5b9392505050565b60005b838110156122bd5781810151838201526020016122a5565b50506000910152565b600082516122d88184602087016122a2565b9190910192915050565b60208152600082518060208401526123018160408501602087016122a2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122099c4fec836f01952667913142136ee80fb4dcb36d3f71f5f3aecc4c5a2a2cf4064736f6c63430008130033", + "numDeployments": 11, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmountOut\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippage\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"path\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Router.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2ExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippage\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"}],\"internalType\":\"struct IUniV2Router.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2ExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2RouterFacet.sol\":\"UniV2RouterFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\ninterface IUniswapV2Router01 {\\n function factory() external pure returns (address);\\n function WETH() external pure returns (address);\\n\\n function addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB, uint liquidity);\\n function addLiquidityETH(\\n address token,\\n uint amountTokenDesired,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\\n function removeLiquidity(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETH(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountToken, uint amountETH);\\n function removeLiquidityWithPermit(\\n address tokenA,\\n address tokenB,\\n uint liquidity,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountA, uint amountB);\\n function removeLiquidityETHWithPermit(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountToken, uint amountETH);\\n function swapExactTokensForTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapTokensForExactTokens(\\n uint amountOut,\\n uint amountInMax,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external returns (uint[] memory amounts);\\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\\n external\\n returns (uint[] memory amounts);\\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\\n external\\n payable\\n returns (uint[] memory amounts);\\n\\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\\n}\\n\",\"keccak256\":\"0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2\"},\"@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol\":{\"content\":\"pragma solidity >=0.6.2;\\n\\nimport './IUniswapV2Router01.sol';\\n\\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\\n function removeLiquidityETHSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline\\n ) external returns (uint amountETH);\\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\\n address token,\\n uint liquidity,\\n uint amountTokenMin,\\n uint amountETHMin,\\n address to,\\n uint deadline,\\n bool approveMax, uint8 v, bytes32 r, bytes32 s\\n ) external returns (uint amountETH);\\n\\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external payable;\\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\\n uint amountIn,\\n uint amountOutMin,\\n address[] calldata path,\\n address to,\\n uint deadline\\n ) external;\\n}\\n\",\"keccak256\":\"0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2RouterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract UniV2RouterFacet is IUniV2Router {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2ExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert Errors.DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountOut =\\n ((params.amountIn * 997) * reserveOut) /\\n ((reserveIn * 1000) + (params.amountIn * 997));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert Errors.InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert Errors.IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(pair).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (amountOut == 0) {\\n revert Errors.ZeroAmountOut();\\n }\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2ExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert Errors.DeadlineExpired();\\n }\\n\\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\\n\\n uint256 pathLengthMinusOne = params.path.length - 1;\\n bool isFromEth = params.path[0] == address(0);\\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\\n\\n if (isFromEth) {\\n params.path[0] = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.path[pathLengthMinusOne] = address(s.weth);\\n }\\n\\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\\n s.uniswapV2Factory,\\n params.amountIn,\\n params.path\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\\n revert Errors.InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert Errors.IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.path[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\\n }\\n\\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < pathLengthMinusOne; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(pairs[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n ++index;\\n }\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.path[pathLengthMinusOne],\\n params.feeBps,\\n params.amountOut,\\n amounts[pathLengthMinusOne]\\n );\\n\\n if (amountOut == 0) {\\n revert Errors.ZeroAmountOut();\\n }\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0a2bbc85be40fe68b818273525f6f27131c289aa5cb1055dc12f648f75ef0e32\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Router {\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippage;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] path;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippage;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n }\\n\\n function uniswapV2ExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2ExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x04db3ffbad9f379af7d52a6af9b8f6e703db0df3ecb0a342804120aac06ee8b2\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0x9b80854a259f0f4fe4e72968297f1d28afe40d9c62a6d59df007568be79f8b02\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Router.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibUniV2Router {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\\n\\n struct DiamondStorage {\\n bool isInitialized;\\n IWETH weth;\\n IUniswapV2Router02 uniswapV2router02;\\n address uniswapV2Factory;\\n IPermit2 permit2;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n\\n assembly {\\n s.slot := position\\n }\\n }\\n\\n // calculates the CREATE2 address for a pair without making any external calls\\n // NOTE: Modified to work with newer Solidity\\n function pairFor(\\n address factory,\\n address tokenA,\\n address tokenB\\n ) internal pure returns (address pair) {\\n if (tokenA > tokenB) {\\n (tokenA, tokenB) = (tokenB, tokenA);\\n }\\n\\n pair = address(\\n uint160(\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n hex'ff',\\n factory,\\n keccak256(abi.encodePacked(tokenA, tokenB)),\\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\\n )\\n )\\n )\\n )\\n );\\n }\\n\\n function getPairsAndAmountsFromPath(\\n address factory,\\n uint256 amountIn,\\n address[] memory path\\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\\n uint256 pathLengthMinusOne = path.length - 1;\\n\\n pairs = new address[](pathLengthMinusOne);\\n amounts = new uint256[](path.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < pathLengthMinusOne; ) {\\n address token0 = path[index];\\n address token1 = path[index + 1];\\n\\n pairs[index] = pairFor(factory, token0, token1);\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\\n .getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4361775eb2d3cf877967ca8f4920daa676dea87c73bce2e55ca4208d1d2dd78b\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50612369806100206000396000f3fe6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611dde565b610066565b60405190815260200160405180910390f35b610041610061366004611eda565b610a8c565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e590600190611fe5565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015160008151811061011757610117611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061016757610167611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061024657610246611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff9092169161122e565b915091506102ca89602001518a606001516114d3565b81600183516102d99190611fe5565b815181106102e9576102e9611ff8565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b50505050506104558260008151811061040457610404611ff8565b60200260200101518a600001518b60e0015160008151811061042857610428611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c8611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e9190612027565b6040518563ffffffff1660e01b815260040161058d9493929190612093565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f8611ff8565b60200260200101518c600001518d60e0015160008151811061061c5761061c611ff8565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c1826001612155565b905060008b60e0015182815181106106db576106db611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e00151516107529190611fe5565b841061075e5730610779565b85838151811061077057610770611ff8565b60200260200101515b905085848151811061078d5761078d611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c7611ff8565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f5611ff8565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f48960c001518a60e0015187815181106108c3576108c3611ff8565b60200260200101518b608001518c60200151858a815181106108e7576108e7611ff8565b6020026020010151611595565b965086600003610930576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a615785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a557600080fd5b505af11580156109b9573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1b576040519150601f19603f3d011682016040523d82523d6000602084013e610a20565b606091505b5050905080610a5b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a80565b610a808960400151888b60e00151888151811061042857610428611ff8565b50505050505092915050565b60008260a0015165ffffffffffff16421115610ad4576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610b46578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610b7057825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610ba59273ffffffffffffffffffffffffffffffffffffffff90911691611656565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610c7d57905b88516103e58082026103e88502019183020281610c9c57610c9c6121d6565b049650610cb189602001518a606001516114d3565b871015610cea576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ddd5788513414610d2a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b50508b5160e08d0151610dd8945073ffffffffffffffffffffffffffffffffffffffff169250869150611503565b610f5e565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610e69908d018d612027565b6040518563ffffffff1660e01b8152600401610e889493929190612093565b600060405180830381600087803b158015610ea257600080fd5b505af1158015610eb6573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff1610610fa3576000610fa6565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610fcf5789610fd2565b60005b83610fde576000610fe0565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506110808a60c001518b61010001518c608001518d602001518c611595565b9750876000036110bc576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156111ed5786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561113157600080fd5b505af1158015611145573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d80600081146111a7576040519150601f19603f3d011682016040523d82523d6000602084013e6111ac565b606091505b50509050806111e7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611221565b6112218a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b5050505050505092915050565b6060806000600184516112419190611fe5565b90508067ffffffffffffffff81111561125c5761125c611c43565b604051908082528060200260200182016040528015611285578160200160208202803683370190505b509250835167ffffffffffffffff8111156112a2576112a2611c43565b6040519080825280602002602001820160405280156112cb578160200160208202803683370190505b50915084826000815181106112e2576112e2611ff8565b60200260200101818152505060005b818110156114c957600085828151811061130d5761130d611ff8565b602002602001015190506000868360016113279190612155565b8151811061133757611337611ff8565b6020026020010151905061134c898383611656565b86848151811061135e5761135e611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806113a68b8585611656565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561146f57905b896103e502826103e80201818b6103e502028161148e5761148e6121d6565b049950898761149e876001612155565b815181106114ae576114ae611ff8565b60209081029190910101525050600190920191506112f19050565b5050935093915050565b60006127106114e28382612205565b6114f09061ffff1685612227565b6114fa919061223e565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115909084906117af565b505050565b60006107d061ffff851611156115e0576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156115f2575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561162c576064603284020461162f565b60005b9050808303838214611647576116478a8a84846118be565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611690579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016117719291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b6000611811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119c39092919063ffffffff16565b90508051600014806118325750808060200190518101906118329190612279565b611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016115d7565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff84161561192e5773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061192c90856119da565b505b61193881866119da565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119d284846000856119fc565b949350505050565b60006114fa8373ffffffffffffffffffffffffffffffffffffffff8416611b15565b606082471015611a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016115d7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab791906122c6565b60006040518083038185875af1925050503d8060008114611af4576040519150601f19603f3d011682016040523d82523d6000602084013e611af9565b606091505b5091509150611b0a87838387611b64565b979650505050505050565b6000818152600183016020526040812054611b5c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114fd565b5060006114fd565b60608315611bfa578251600003611bf35773ffffffffffffffffffffffffffffffffffffffff85163b611bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115d7565b50816119d2565b6119d28383815115611c0f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d791906122e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611c9657611c96611c43565b60405290565b604051610120810167ffffffffffffffff81118282101715611c9657611c96611c43565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ce457600080fd5b919050565b803561ffff81168114611ce457600080fd5b803565ffffffffffff81168114611ce457600080fd5b600082601f830112611d2257600080fd5b8135602067ffffffffffffffff80831115611d3f57611d3f611c43565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611d8257611d82611c43565b604052938452858101830193838101925087851115611da057600080fd5b83870191505b84821015611b0a57611db782611cc0565b83529183019190830190611da6565b600060408284031215611dd857600080fd5b50919050565b60008060408385031215611df157600080fd5b823567ffffffffffffffff80821115611e0957600080fd5b908401906101008287031215611e1e57600080fd5b611e26611c72565b8235815260208301356020820152611e4060408401611cc0565b6040820152611e5160608401611ce9565b6060820152611e6260808401611ce9565b6080820152611e7360a08401611cfb565b60a0820152611e8460c08401611cc0565b60c082015260e083013582811115611e9b57600080fd5b611ea788828601611d11565b60e08301525093506020850135915080821115611ec357600080fd5b50611ed085828601611dc6565b9150509250929050565b600080828403610140811215611eef57600080fd5b61012080821215611eff57600080fd5b611f07611c9c565b91508435825260208501356020830152611f2360408601611cc0565b6040830152611f3460608601611ce9565b6060830152611f4560808601611ce9565b6080830152611f5660a08601611cfb565b60a0830152611f6760c08601611cc0565b60c0830152611f7860e08601611cc0565b60e0830152610100611f8b818701611cc0565b9083015290925083013567ffffffffffffffff811115611faa57600080fd5b611ed085828601611dc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156114fd576114fd611fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b60200191503681900382131561208c57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b808201808211156114fd576114fd611fb6565b80516dffffffffffffffffffffffffffff81168114611ce457600080fd5b60008060006060848603121561219b57600080fd5b6121a484612168565b92506121b260208501612168565b9150604084015163ffffffff811681146121cb57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff82811682821603908082111561222057612220611fb6565b5092915050565b80820281158282048414176114fd576114fd611fb6565b600082612274577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561228b57600080fd5b8151801515811461229b57600080fd5b9392505050565b60005b838110156122bd5781810151838201526020016122a5565b50506000910152565b600082516122d88184602087016122a2565b9190910192915050565b60208152600082518060208401526123018160408501602087016122a2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220c2ffa202312007b9304d19c6ef1a8c20f251d97ac71d875f76e6b5397d79ae2d64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80630d164c381461002e578063a817b67d14610053575b600080fd5b61004161003c366004611dde565b610066565b60405190815260200160405180910390f35b610041610061366004611eda565b610a8c565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c906000906100e590600190611fe5565b905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015160008151811061011757610117611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061016757610167611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161490508115610205578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e001516000815181106101ca576101ca611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8015610281578360000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff168760e00151848151811061024657610246611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b6002840154875160e089015160009283926102b49273ffffffffffffffffffffffffffffffffffffffff9092169161122e565b915091506102ca89602001518a606001516114d3565b81600183516102d99190611fe5565b815181106102e9576102e9611ff8565b60200260200101511015610329576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b831561045a5788513414610369576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d557600080fd5b505af11580156103e9573d6000803e3d6000fd5b50505050506104558260008151811061040457610404611ff8565b60200260200101518a600001518b60e0015160008151811061042857610428611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b6106a9565b8560030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f60e001516000815181106104c8576104c8611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60a0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff168152508b806020019061056e9190612027565b6040518563ffffffff1660e01b815260040161058d9493929190612093565b600060405180830381600087803b1580156105a757600080fd5b505af11580156105bb573d6000803e3d6000fd5b5050506003870154835173ffffffffffffffffffffffffffffffffffffffff90911691506336c7851690339085906000906105f8576105f8611ff8565b60200260200101518c600001518d60e0015160008151811061061c5761061c611ff8565b60200260200101516040518563ffffffff1660e01b8152600401610676949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b505050505b60005b858110156108a45760006106c1826001612155565b905060008b60e0015182815181106106db576106db611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c60e00151848151811061070f5761070f611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161061073957600061073c565b60015b9050600060028d60e00151516107529190611fe5565b841061075e5730610779565b85838151811061077057610770611ff8565b60200260200101515b905085848151811061078d5761078d611ff8565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f836107d4578685815181106107c7576107c7611ff8565b60200260200101516107d7565b60005b846107e35760006107fe565b8786815181106107f5576107f5611ff8565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561087e57600080fd5b505af1158015610892573d6000803e3d6000fd5b505050508360010193505050506106ac565b506108f48960c001518a60e0015187815181106108c3576108c3611ff8565b60200260200101518b608001518c60200151858a815181106108e7576108e7611ff8565b6020026020010151611595565b965086600003610930576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215610a615785546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156109a557600080fd5b505af11580156109b9573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610a1b576040519150601f19603f3d011682016040523d82523d6000602084013e610a20565b606091505b5050905080610a5b576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610a80565b610a808960400151888b60e00151888151811061042857610428611ff8565b50505050505092915050565b60008260a0015165ffffffffffff16421115610ad4576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517fcd4d5c78b9e1b4c12c165f6dabad75194d4ff180375bd5b3c4499489a642191c9173ffffffffffffffffffffffffffffffffffffffff908116159116158115610b46578254610100900473ffffffffffffffffffffffffffffffffffffffff1660e08701525b8015610b7057825473ffffffffffffffffffffffffffffffffffffffff6101009182900416908701525b600283015460e0870151610100880151600092610ba59273ffffffffffffffffffffffffffffffffffffffff90911691611656565b90506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff161115610c7d57905b88516103e58082026103e88502019183020281610c9c57610c9c6121d6565b049650610cb189602001518a606001516114d3565b871015610cea576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610ddd5788513414610d2a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b50508b5160e08d0151610dd8945073ffffffffffffffffffffffffffffffffffffffff169250869150611503565b610f5e565b60038601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d518216608084015260a0808f01805165ffffffffffff908116928601929092528e35821660c0860152918452306020808601919091529151169383019390935290921691632b67b57091339190610e69908d018d612027565b6040518563ffffffff1660e01b8152600401610e889493929190612093565b600060405180830381600087803b158015610ea257600080fd5b505af1158015610eb6573d6000803e3d6000fd5b505050506003860154895160e08b01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8781166024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff1610610fa3576000610fa6565b60015b90508373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f82610fcf5789610fd2565b60005b83610fde576000610fe0565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506110808a60c001518b61010001518c608001518d602001518c611595565b9750876000036110bc576040517f4497be8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156111ed5786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905261010090910473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561113157600080fd5b505af1158015611145573d6000803e3d6000fd5b5050505060008a6040015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d80600081146111a7576040519150601f19603f3d011682016040523d82523d6000602084013e6111ac565b606091505b50509050806111e7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611221565b6112218a60400151898c610100015173ffffffffffffffffffffffffffffffffffffffff166115039092919063ffffffff16565b5050505050505092915050565b6060806000600184516112419190611fe5565b90508067ffffffffffffffff81111561125c5761125c611c43565b604051908082528060200260200182016040528015611285578160200160208202803683370190505b509250835167ffffffffffffffff8111156112a2576112a2611c43565b6040519080825280602002602001820160405280156112cb578160200160208202803683370190505b50915084826000815181106112e2576112e2611ff8565b60200260200101818152505060005b818110156114c957600085828151811061130d5761130d611ff8565b602002602001015190506000868360016113279190612155565b8151811061133757611337611ff8565b6020026020010151905061134c898383611656565b86848151811061135e5761135e611ff8565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506000806113a68b8585611656565b73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190612186565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561146f57905b896103e502826103e80201818b6103e502028161148e5761148e6121d6565b049950898761149e876001612155565b815181106114ae576114ae611ff8565b60209081029190910101525050600190920191506112f19050565b5050935093915050565b60006127106114e28382612205565b6114f09061ffff1685612227565b6114fa919061223e565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526115909084906117af565b505050565b60006107d061ffff851611156115e0576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b600082848111156115f2575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561162c576064603284020461162f565b60005b9050808303838214611647576116478a8a84846118be565b50505090910395945050505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115611690579091905b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085811b8216602084015284901b1660348201528490604801604051602081830303815290604052805190602001206040516020016117719291907fff00000000000000000000000000000000000000000000000000000000000000815260609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016600183015260158201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f603582015260550190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120949350505050565b6000611811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119c39092919063ffffffff16565b90508051600014806118325750808060200190518101906118329190612279565b611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016115d7565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff84161561192e5773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061192c90856119da565b505b61193881866119da565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119d284846000856119fc565b949350505050565b60006114fa8373ffffffffffffffffffffffffffffffffffffffff8416611b15565b606082471015611a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016115d7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab791906122c6565b60006040518083038185875af1925050503d8060008114611af4576040519150601f19603f3d011682016040523d82523d6000602084013e611af9565b606091505b5091509150611b0a87838387611b64565b979650505050505050565b6000818152600183016020526040812054611b5c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114fd565b5060006114fd565b60608315611bfa578251600003611bf35773ffffffffffffffffffffffffffffffffffffffff85163b611bf3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016115d7565b50816119d2565b6119d28383815115611c0f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d791906122e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611c9657611c96611c43565b60405290565b604051610120810167ffffffffffffffff81118282101715611c9657611c96611c43565b803573ffffffffffffffffffffffffffffffffffffffff81168114611ce457600080fd5b919050565b803561ffff81168114611ce457600080fd5b803565ffffffffffff81168114611ce457600080fd5b600082601f830112611d2257600080fd5b8135602067ffffffffffffffff80831115611d3f57611d3f611c43565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611d8257611d82611c43565b604052938452858101830193838101925087851115611da057600080fd5b83870191505b84821015611b0a57611db782611cc0565b83529183019190830190611da6565b600060408284031215611dd857600080fd5b50919050565b60008060408385031215611df157600080fd5b823567ffffffffffffffff80821115611e0957600080fd5b908401906101008287031215611e1e57600080fd5b611e26611c72565b8235815260208301356020820152611e4060408401611cc0565b6040820152611e5160608401611ce9565b6060820152611e6260808401611ce9565b6080820152611e7360a08401611cfb565b60a0820152611e8460c08401611cc0565b60c082015260e083013582811115611e9b57600080fd5b611ea788828601611d11565b60e08301525093506020850135915080821115611ec357600080fd5b50611ed085828601611dc6565b9150509250929050565b600080828403610140811215611eef57600080fd5b61012080821215611eff57600080fd5b611f07611c9c565b91508435825260208501356020830152611f2360408601611cc0565b6040830152611f3460608601611ce9565b6060830152611f4560808601611ce9565b6080830152611f5660a08601611cfb565b60a0830152611f6760c08601611cc0565b60c0830152611f7860e08601611cc0565b60e0830152610100611f8b818701611cc0565b9083015290925083013567ffffffffffffffff811115611faa57600080fd5b611ed085828601611dc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156114fd576114fd611fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261205c57600080fd5b83018035915067ffffffffffffffff82111561207757600080fd5b60200191503681900382131561208c57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b808201808211156114fd576114fd611fb6565b80516dffffffffffffffffffffffffffff81168114611ce457600080fd5b60008060006060848603121561219b57600080fd5b6121a484612168565b92506121b260208501612168565b9150604084015163ffffffff811681146121cb57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b61ffff82811682821603908082111561222057612220611fb6565b5092915050565b80820281158282048414176114fd576114fd611fb6565b600082612274577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561228b57600080fd5b8151801515811461229b57600080fd5b9392505050565b60005b838110156122bd5781810151838201526020016122a5565b50506000910152565b600082516122d88184602087016122a2565b9190910192915050565b60208152600082518060208401526123018160408501602087016122a2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220c2ffa202312007b9304d19c6ef1a8c20f251d97ac71d875f76e6b5397d79ae2d64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV3Callback.json b/packages/hardhat/deployments/mainnet/UniV3Callback.json index 61e35d01..417d8253 100644 --- a/packages/hardhat/deployments/mainnet/UniV3Callback.json +++ b/packages/hardhat/deployments/mainnet/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0xF126A02d11AE718E3D6C65Dc1e43499566aC3741", + "address": "0x76b7Cd9a3474eE56e6DD1BEc3e085eE0CCc1bf8d", "abi": [ { "inputs": [], @@ -53,28 +53,28 @@ "type": "function" } ], - "transactionHash": "0xdf142a28ff5babdb3498464177a404bb0519621c50276a102e3ddf430db1cd8e", + "transactionHash": "0xaeeb3bcf005c0cfb4bbd4bd413d8284b50adcfb00b00d4a18d5ba6aaec4f62d4", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xF126A02d11AE718E3D6C65Dc1e43499566aC3741", - "transactionIndex": 81, + "contractAddress": "0x76b7Cd9a3474eE56e6DD1BEc3e085eE0CCc1bf8d", + "transactionIndex": 57, "gasUsed": "480364", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xab834ef51236fa08688ce09c846190234f4e73793aed174a4ca46bbfb30642a8", - "transactionHash": "0xdf142a28ff5babdb3498464177a404bb0519621c50276a102e3ddf430db1cd8e", + "blockHash": "0x053d33f4e2a9adcf31de688bbdbfbdefcc45fd54a7c8d979f4a89c0a02789ee2", + "transactionHash": "0xaeeb3bcf005c0cfb4bbd4bd413d8284b50adcfb00b00d4a18d5ba6aaec4f62d4", "logs": [], - "blockNumber": 18181197, - "cumulativeGasUsed": "9216434", + "blockNumber": 18217274, + "cumulativeGasUsed": "7627983", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/UniV3Like.json b/packages/hardhat/deployments/mainnet/UniV3Like.json index fae2c168..f63e4c1a 100644 --- a/packages/hardhat/deployments/mainnet/UniV3Like.json +++ b/packages/hardhat/deployments/mainnet/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0xA229893E88AABA8c38F1fbf40780679372BFCDE6", + "address": "0xeeaA06C06D807A42D98f5202BCDeBd39C44F192a", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0xffc5bdf0853578f1ee35c6bc06fddd59a43d829e2bca21713dcc2540713d0bdd", + "transactionHash": "0x6f9e1835b8651019bae155af54ff4ca8a20db9e60fcfa5920218171f98e4d8f4", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xA229893E88AABA8c38F1fbf40780679372BFCDE6", - "transactionIndex": 67, + "contractAddress": "0xeeaA06C06D807A42D98f5202BCDeBd39C44F192a", + "transactionIndex": 110, "gasUsed": "1989716", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x345e4b64f3a977a639f553456e9e7d5ac4ba7b4326c65972cf8ad544d6fc7095", - "transactionHash": "0xffc5bdf0853578f1ee35c6bc06fddd59a43d829e2bca21713dcc2540713d0bdd", + "blockHash": "0x71bbbcd86aa7b2ca317c2a66adf101b6fea298e2584c158d136acfc57d11a4be", + "transactionHash": "0x6f9e1835b8651019bae155af54ff4ca8a20db9e60fcfa5920218171f98e4d8f4", "logs": [], - "blockNumber": 18181198, - "cumulativeGasUsed": "7503727", + "blockNumber": 18217281, + "cumulativeGasUsed": "11962691", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89bc1011edc38e6b0575be8b7f43aa2530bff8eaeff5da0ad1f479da30b0a84\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x3d5f724620e8dffd077b86613050bca34d60dab1288090558a63db18c8a8b9b1\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24d951973c414bf7384ab3c8862934f4ea125ba750c0f15f804325faa79a6a6c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xec1f28bdd5499b3065bebb77fa28e1a5b03dd07d22cb0273987f8f3dc9796096\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/WarpLink.json b/packages/hardhat/deployments/mainnet/WarpLink.json index 35197bfb..af4e3cbf 100644 --- a/packages/hardhat/deployments/mainnet/WarpLink.json +++ b/packages/hardhat/deployments/mainnet/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0x073E9Fb90D07d751544F57B0a66aF9B073E2B32e", + "address": "0xb052C31125bd11a66431E1c4A735A1d965652C77", "abi": [ { "inputs": [], @@ -16,11 +16,6 @@ "name": "DeadlineExpired", "type": "error" }, - { - "inputs": [], - "name": "EthNotSupportedForWarp", - "type": "error" - }, { "inputs": [ { @@ -34,17 +29,17 @@ }, { "inputs": [], - "name": "InconsistentPartPayerOut", + "name": "IllegalJumpInSplit", "type": "error" }, { "inputs": [], - "name": "InconsistentPartTokenOut", + "name": "InconsistentPartPayerOut", "type": "error" }, { "inputs": [], - "name": "IncorrectEthValue", + "name": "InconsistentPartTokenOut", "type": "error" }, { @@ -54,261 +49,63 @@ }, { "inputs": [], - "name": "InsufficientOutputAmount", + "name": "InsufficientEthValue", "type": "error" }, { "inputs": [], - "name": "InsufficientTokensDelivered", + "name": "InsufficientOutputAmount", "type": "error" }, { "inputs": [], - "name": "NotEnoughParts", + "name": "InsufficientTokensDelivered", "type": "error" }, { "inputs": [], - "name": "UnexpectedPayerForWrap", + "name": "JumpMustBeLastCommand", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForUnwrap", + "name": "NativeTokenNotSupported", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForWrap", + "name": "NotEnoughParts", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenOut", + "name": "UnexpectedPayerForWrap", "type": "error" }, { "inputs": [], - "name": "UnexpectedValueAndTokenCombination", + "name": "UnexpectedTokenForUnwrap", "type": "error" }, { "inputs": [], - "name": "UnhandledCommand", + "name": "UnexpectedTokenForWrap", "type": "error" }, { "inputs": [], - "name": "UnhandledPoolKind", + "name": "UnexpectedTokenOut", "type": "error" }, { "inputs": [], - "name": "COMMAND_TYPE_SPLIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_UNWRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeSplit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeUnwrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpCurveExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledCommand", + "type": "error" }, { "inputs": [], - "name": "commandTypeWrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledPoolKind", + "type": "error" }, { "inputs": [ @@ -393,28 +190,28 @@ "type": "function" } ], - "transactionHash": "0x9dd3c4cb6a7ea6128a0b63bb79febf30efb9d23287333a29d86db73abf372e9e", + "transactionHash": "0x7ad76ebd827c0f561a6b692b23852e0d4e2c6b76d5c3ad71e536078d84d01d5d", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x073E9Fb90D07d751544F57B0a66aF9B073E2B32e", - "transactionIndex": 93, - "gasUsed": "3603983", + "contractAddress": "0xb052C31125bd11a66431E1c4A735A1d965652C77", + "transactionIndex": 7, + "gasUsed": "3924450", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8d22d840c496546a70ffcbfe7bf98bad1d560e7af051a297fc4f444d4d11cb03", - "transactionHash": "0x9dd3c4cb6a7ea6128a0b63bb79febf30efb9d23287333a29d86db73abf372e9e", + "blockHash": "0x85d555f964ce317661b79c15a7acf135a35560c3c0cebf4679e6ff39294b28aa", + "transactionHash": "0x7ad76ebd827c0f561a6b692b23852e0d4e2c6b76d5c3ad71e536078d84d01d5d", "logs": [], - "blockNumber": 18181199, - "cumulativeGasUsed": "10762940", + "blockNumber": 18217284, + "cumulativeGasUsed": "5330202", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthNotSupportedForWarp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedValueAndTokenCombination\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_SPLIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_UNWRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeSplit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeUnwrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpCurveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract WarpLink is IWarpLink {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct TransientState {\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n }\\n\\n uint256 public constant COMMAND_TYPE_WRAP = 1;\\n uint256 public constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 public constant COMMAND_TYPE_SPLIT = 4;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 public constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n\\n function commandTypeWrap() external pure returns (uint256) {\\n return COMMAND_TYPE_WRAP;\\n }\\n\\n function commandTypeUnwrap() external pure returns (uint256) {\\n return COMMAND_TYPE_UNWRAP;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeSplit() external pure returns (uint256) {\\n return COMMAND_TYPE_SPLIT;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn != address(0)) {\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n TransientState memory t;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (msg.value == 0) {\\n if (params.tokenIn == address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n } else {\\n if (params.tokenIn != address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd9e99e7f5322f064977ea54517ad3889c4b74b1828d18c79e0490e06e2295a09\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedValueAndTokenCombination();\\n error UnexpectedPayerForWrap();\\n error EthNotSupportedForWarp();\\n error DeadlineExpired();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n\\n function commandTypeWrap() external pure returns (uint256);\\n\\n function commandTypeUnwrap() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeSplit() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa25e901022a1fc4f1bddb4e10cdce3a8963172ff1a8af9f4a2000ab0959876e7\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6c564dca55e92d9ee1c546a75a68d4e7c8799773f59f2aab4ea72cc70e601dff\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061409b806100206000396000f3fe60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "df6263755b6a66e75866b356448256e7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IllegalJumpInSplit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JumpMustBeLastCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nabstract contract WarpLinkCommandTypes {\\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\\n}\\n\\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct JumpStargateParams {\\n uint16 dstChainId;\\n uint256 srcPoolId;\\n uint256 dstPoolId;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n /**\\n * 0 or 1\\n */\\n uint256 jumped;\\n /**\\n * The amount of native value not spent. The native value starts off as\\n * `msg.value - params.amount` and is decreased by spending money on jumps.\\n *\\n * Any leftover native value is returned to `msg.sender`\\n */\\n uint256 nativeValueRemaining;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (tPart.jumped == 1) {\\n revert IllegalJumpInSplit();\\n }\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\n *\\n * The token must not be ETH (0)\\n *\\n * After this operation, the token will be unchanged and `t.amount` will\\n * be how much was sent. `t.jumped` will be set to `1` to indicate\\n * that no more commands should be run\\n *\\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\\n * because only `t.token` can be moved by Stargate.\\n *\\n * This command must not run inside of a split.\\n *\\n * A bridge fee must be paid in the native token. This fee is determined with\\n * `IStargateRouter.quoteLayerZeroFee`\\n *\\n * The value for `t.token` remains the same and is not chained.\\n *\\n * Params are read from the stream as:\\n * - dstChainId (uint16)\\n * - srcPoolId (uint8)\\n * - dstPoolId (uint8)\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n // NOTE: There is a WETH pool\\n revert NativeTokenNotSupported();\\n }\\n\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibKitty.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens\\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\\n }\\n\\n t.jumped = 1;\\n\\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // Max 5% slippage\\n _minAmountLD: (t.amount * 95) / 100,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(t.paramRecipient),\\n _payload: ''\\n });\\n\\n t.nativeValueRemaining = 0;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\\n if (commandIndex != commandCount - 1) {\\n revert JumpMustBeLastCommand();\\n }\\n\\n t = processJumpStargate(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramRecipient = params.recipient;\\n t.paramAmountOut = params.amountOut;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (params.tokenIn == address(0)) {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n t.nativeValueRemaining = msg.value - params.amountIn;\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n } else {\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n\\n t.nativeValueRemaining = msg.value;\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n if (t.jumped == 1) {\\n // The coins have jumped away from this chain. Fees were collected before the jump\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0be7a956a725d437c18e3bc2a96f09804a20c04d17feac9ac895b503152c13e2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error InsufficientEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedPayerForWrap();\\n error NativeTokenNotSupported();\\n error DeadlineExpired();\\n error IllegalJumpInSplit();\\n error JumpMustBeLastCommand();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n}\\n\",\"keccak256\":\"0x9242d5352942101b05bea1dcaea4b057473c4c2ae65214618f5361a18e194daa\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1c4eccca88e3487c6b6663ce51b77ea778e91b801373223e998fe96e2fff1750\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50614669806100206000396000f3fe60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/mainnet/solcInputs/025166ddb0f771753ceec554ac05c5f7.json b/packages/hardhat/deployments/mainnet/solcInputs/025166ddb0f771753ceec554ac05c5f7.json new file mode 100644 index 00000000..d03365ab --- /dev/null +++ b/packages/hardhat/deployments/mainnet/solcInputs/025166ddb0f771753ceec554ac05c5f7.json @@ -0,0 +1,161 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and the amount will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * This command cannot run inside of a split\n *\n * No more commands should execute after this command since the tokens\n * have all left the chain\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * IStargateRouter.quoteLayerZeroFee\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint256)\n * - dstPoolId (uint256)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n // TODO: Make a new error or rename the existing\n revert EthNotSupportedForWarp();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // The value for `t.token` remains the same and is not chained. It is possible that the user\n // has constructed a command where the srcPoolId is not of the token t.token. This should not\n // be dangerous because only `t.token` is allowed to be transferred\n\n // Collect fees\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: uint16(params.dstChainId),\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // TODO: If the min amount is not met, is the tx reverted or is this refunded?\n _minAmountLD: 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encode(uint256(uint160(t.paramRecipient))),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2, address router) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n s.stargateRouter = IStargateRouter(router);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/mainnet/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json b/packages/hardhat/deployments/mainnet/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json new file mode 100644 index 00000000..d3c23a0d --- /dev/null +++ b/packages/hardhat/deployments/mainnet/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json @@ -0,0 +1,191 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "contracts/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\n\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\n// The EIP-2535 Diamond standard requires these functions.\n\ncontract DiamondLoupeFacet is IDiamondLoupe {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; i++) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n }\n}\n" + }, + "contracts/facets/KittyFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IKitty} from '../interfaces/IKitty.sol';\n\ncontract KittyFacet is IKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n error InsufficientOwnerBalance(uint256 available);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\n LibKitty.State storage s = LibKitty.state();\n\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\n uint256 length = tokenSet.length();\n\n tokens_ = new address[](length);\n\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\n }\n }\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\n LibKitty.State storage s = LibKitty.state();\n\n return s.partnerBalances[partner][token];\n }\n\n function partnerWithdraw(address token) external {\n LibKitty.State storage s = LibKitty.state();\n\n uint256 balance = s.partnerBalances[msg.sender][token];\n\n if (balance > 0) {\n s.partnerBalances[msg.sender][token] = 0;\n s.partnerBalancesTotal[token] -= balance;\n\n emit PartnerWithdraw(msg.sender, token, balance);\n\n if (token == address(0)) {\n // NOTE: Control transfered to untrusted address\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n // NOTE: The token is not removed from the partner's token set\n IERC20(token).safeTransfer(msg.sender, balance);\n }\n }\n }\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\n LibDiamond.enforceIsContractOwner();\n\n LibKitty.State storage s = LibKitty.state();\n\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\n\n uint256 balance = token == address(0)\n ? address(this).balance\n : IERC20(token).balanceOf(address(this));\n\n uint256 available = balance - partnerBalanceTotal;\n\n if (amount > available) {\n revert InsufficientOwnerBalance(available);\n }\n\n if (token == address(0)) {\n // Send ETH\n (bool sent, ) = to.call{value: amount}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(token).safeTransfer(to, amount);\n }\n }\n}\n" + }, + "contracts/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IERC173} from '../interfaces/IERC173.sol';\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct TransientState {\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn != address(0)) {\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n TransientState memory t;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (msg.value == 0) {\n if (params.tokenIn == address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n } else {\n if (params.tokenIn != address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/DiamondMultiInit.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\n\ncontract DiamondMultiInit {\n // This function is provided in the third parameter of the `diamondCut` function.\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\n\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\n if (_addresses.length != _calldata.length) {\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\n }\n for (uint i; i < _addresses.length; i++) {\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/init/InitUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitUniV2Router {\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n if (!s.isInitialized) {\n s.isInitialized = true;\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\n s.weth = IWETH(s.uniswapV2router02.WETH());\n }\n\n s.uniswapV2Factory = uniswapV2Factory;\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Factory.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" + }, + "contracts/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/IKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\n\ninterface IKitty {\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\n\n function partnerWithdraw(address token) external;\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedValueAndTokenCombination();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/SifiDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from './libraries/LibDiamond.sol';\nimport {IDiamondCut} from './interfaces/IDiamondCut.sol';\nimport {IDiamondLoupe} from './interfaces/IDiamondLoupe.sol';\n\ncontract SifiDiamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), '');\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), 'Diamond: Function does not exist');\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n receive() external payable {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/mainnet/solcInputs/df6263755b6a66e75866b356448256e7.json b/packages/hardhat/deployments/mainnet/solcInputs/df6263755b6a66e75866b356448256e7.json new file mode 100644 index 00000000..958f2b3a --- /dev/null +++ b/packages/hardhat/deployments/mainnet/solcInputs/df6263755b6a66e75866b356448256e7.json @@ -0,0 +1,119 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and `t.amount` will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\n * because only `t.token` can be moved by Stargate.\n *\n * This command must not run inside of a split.\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * `IStargateRouter.quoteLayerZeroFee`\n *\n * The value for `t.token` remains the same and is not chained.\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint8)\n * - dstPoolId (uint8)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n revert NativeTokenNotSupported();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // Max 5% slippage\n _minAmountLD: (t.amount * 95) / 100,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(t.paramRecipient),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error NativeTokenNotSupported();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/optimism/Curve.json b/packages/hardhat/deployments/optimism/Curve.json index 00912d98..dacf670a 100644 --- a/packages/hardhat/deployments/optimism/Curve.json +++ b/packages/hardhat/deployments/optimism/Curve.json @@ -1,5 +1,5 @@ { - "address": "0xd8c18A7CcA4576156dD6d11132799E649A591B3E", + "address": "0xC934b2636ACF7803eb75964fEb88797D5EEA1b2a", "abi": [ { "inputs": [], @@ -141,28 +141,28 @@ "type": "function" } ], - "transactionHash": "0x58a2908a0609bc8bb815be04950245779253a57c19f60ab9918c388c17eb0b98", + "transactionHash": "0xd90d489afdfd1db36dd6717874444172489ff744fc1bc8c4ce120cdb5a89d135", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd8c18A7CcA4576156dD6d11132799E649A591B3E", - "transactionIndex": 6, + "contractAddress": "0xC934b2636ACF7803eb75964fEb88797D5EEA1b2a", + "transactionIndex": 4, "gasUsed": "1277511", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcb20fc69f391bbeb443dc93a03904e1db17cafa5a5a7d960f828e91b7f9005b1", - "transactionHash": "0x58a2908a0609bc8bb815be04950245779253a57c19f60ab9918c388c17eb0b98", + "blockHash": "0xf8d337485e5677c21b5cbfdd836815ca07cb8fda5b0e9aadb34f4849d21cc5df", + "transactionHash": "0xd90d489afdfd1db36dd6717874444172489ff744fc1bc8c4ce120cdb5a89d135", "logs": [], - "blockNumber": 109831856, - "cumulativeGasUsed": "1896662", + "blockNumber": 110049074, + "cumulativeGasUsed": "1645464", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26a236ab658af7341bd585a6fd11474bb627ba050aca1c08532cd29c72d314c9\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x377723b233f7e22e77f9b0da81d8fb8f78d5adcdb6bb7817f06e602dea6f182e\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb8f29211d45827b00c6c594b8f0b68517a33881f55d8988a06d0721df488ce12\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x7439d7d6a66ec29616591dcfe8252bd92ec4852f58edcfb9b1e7102d1d43b74c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/DiamondCutFacet.json b/packages/hardhat/deployments/optimism/DiamondCutFacet.json index ae0e3d4f..02699b4c 100644 --- a/packages/hardhat/deployments/optimism/DiamondCutFacet.json +++ b/packages/hardhat/deployments/optimism/DiamondCutFacet.json @@ -1,5 +1,5 @@ { - "address": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", + "address": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", "abi": [ { "inputs": [ @@ -100,28 +100,28 @@ "type": "function" } ], - "transactionHash": "0x5994f0b6b200fd7d37bfb1a5e5e4d73602f517d3d09cfbb3fb99011e0af5bae9", + "transactionHash": "0x76c22dabf384f5f249d665399f402d3cd3bf69b1358dfaf45cc208a774f245a0", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", - "transactionIndex": 10, + "contractAddress": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", + "transactionIndex": 6, "gasUsed": "1562880", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa253634b1d6ed04fe5a54bf571fe6d2be92c058567eaea359e2acb215a44c840", - "transactionHash": "0x5994f0b6b200fd7d37bfb1a5e5e4d73602f517d3d09cfbb3fb99011e0af5bae9", + "blockHash": "0x614aa9add7101497043e6483b3ecdc1b8083e706c01f4ea8748b68a9525f063c", + "transactionHash": "0x76c22dabf384f5f249d665399f402d3cd3bf69b1358dfaf45cc208a774f245a0", "logs": [], - "blockNumber": 109755116, - "cumulativeGasUsed": "4839471", + "blockNumber": 110048934, + "cumulativeGasUsed": "3061031", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5cd8d244f7163e4db8c139c06517a410", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x862ac209f7309608ba3e033d6f2e185d82936745ae9eff95d78681bd7c09799a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0xfb51534d56cfbfc884869f4c67b3b01fb3303a762418d796feabb78543d289ee\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/optimism/DiamondLoupeFacet.json b/packages/hardhat/deployments/optimism/DiamondLoupeFacet.json index 117fe12c..ff0c2d43 100644 --- a/packages/hardhat/deployments/optimism/DiamondLoupeFacet.json +++ b/packages/hardhat/deployments/optimism/DiamondLoupeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", + "address": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", "abi": [ { "inputs": [ @@ -78,28 +78,28 @@ "type": "function" } ], - "transactionHash": "0xc47d7e1adab73e2dcece55555053f96daf785fd1d1edb01b89130e14fa638a75", + "transactionHash": "0xe92b02faca29547b8bdfc789888e803df1dbece64bb10391ab246e2df2d118fc", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", - "transactionIndex": 1, + "contractAddress": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", + "transactionIndex": 7, "gasUsed": "480128", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xab1653551343a7814188ce1a3037dc7c7040b9096308db25a18cb7ae8e4b0d49", - "transactionHash": "0xc47d7e1adab73e2dcece55555053f96daf785fd1d1edb01b89130e14fa638a75", + "blockHash": "0x2fc47f2faa80bad88313a6326eda726ee8d719dcca31d65384ba5acd6ee1b509", + "transactionHash": "0xe92b02faca29547b8bdfc789888e803df1dbece64bb10391ab246e2df2d118fc", "logs": [], - "blockNumber": 109755126, - "cumulativeGasUsed": "530629", + "blockNumber": 110048944, + "cumulativeGasUsed": "1686125", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5cd8d244f7163e4db8c139c06517a410", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x912f2287b015cd1568157eb79d48033d8db3be846de4c50691d44ad5dc1a638b\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x5edfd8138efb21086b53df2028f755aae576b00a7193102cca00d14beb025475\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/optimism/DiamondMultiInit.json b/packages/hardhat/deployments/optimism/DiamondMultiInit.json index 0c58324a..d0bd998e 100644 --- a/packages/hardhat/deployments/optimism/DiamondMultiInit.json +++ b/packages/hardhat/deployments/optimism/DiamondMultiInit.json @@ -1,5 +1,5 @@ { - "address": "0x88fA496FD35AC5e20D8e59Afc3432197BB10b6F1", + "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", "abi": [ { "inputs": [ @@ -52,28 +52,28 @@ "type": "function" } ], - "transactionHash": "0xd06dc8110020e1e709fcf62bacb17cee5870ec8b8fb6295c7d894db3b423f228", + "transactionHash": "0x9d0b929735d3aa1b17e2b7f7292fbbd25362071d01b5a91e0f0efb40c7137b8e", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x88fA496FD35AC5e20D8e59Afc3432197BB10b6F1", + "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", "transactionIndex": 3, "gasUsed": "358372", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdb7a710814d41a873abce351d2cb080d50a971d22130e6286851085e326a5797", - "transactionHash": "0xd06dc8110020e1e709fcf62bacb17cee5870ec8b8fb6295c7d894db3b423f228", + "blockHash": "0xdc3909a17fefa752be9947467aadf2556638bdf860e232ce677a604d485ca000", + "transactionHash": "0x9d0b929735d3aa1b17e2b7f7292fbbd25362071d01b5a91e0f0efb40c7137b8e", "logs": [], - "blockNumber": 109755173, - "cumulativeGasUsed": "1996833", + "blockNumber": 110049104, + "cumulativeGasUsed": "623117", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5cd8d244f7163e4db8c139c06517a410", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7039f6a07145a76f91a7f976a7f6af7fba83d559a3f895e6c425fe1fbd239fce\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8a6197389eba7856703a1fbabf7ecdd760678fcaf61be646731a14e4f88e80e9\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/InitLibWarp.json b/packages/hardhat/deployments/optimism/InitLibWarp.json index 56439378..689fbd19 100644 --- a/packages/hardhat/deployments/optimism/InitLibWarp.json +++ b/packages/hardhat/deployments/optimism/InitLibWarp.json @@ -1,5 +1,5 @@ { - "address": "0x9fEDE519d846E1165c843872C62f74c353a6Cfd1", + "address": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", "abi": [ { "inputs": [ @@ -12,6 +12,11 @@ "internalType": "address", "name": "permit2", "type": "address" + }, + { + "internalType": "address", + "name": "router", + "type": "address" } ], "name": "init", @@ -20,28 +25,28 @@ "type": "function" } ], - "transactionHash": "0xf7131d8f5443b55c4fcc3d1cb8bba3b25861ca123297db4d9648b314fd6fdcb7", + "transactionHash": "0xc1b9f777fc39dea3b536638a4ef9594c31dfb26688d8698ef3224edda5f8d091", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x9fEDE519d846E1165c843872C62f74c353a6Cfd1", - "transactionIndex": 7, - "gasUsed": "129799", + "contractAddress": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", + "transactionIndex": 3, + "gasUsed": "143671", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7b93917ab49397befdb395e7f2f55d8fdbf1ca633a0d3a149008180a9088b059", - "transactionHash": "0xf7131d8f5443b55c4fcc3d1cb8bba3b25861ca123297db4d9648b314fd6fdcb7", + "blockHash": "0x0c8cd933f39ffc4219de1e05c77418526df2b6a0899a701c20289aeb40ba3878", + "transactionHash": "0xc1b9f777fc39dea3b536638a4ef9594c31dfb26688d8698ef3224edda5f8d091", "logs": [], - "blockNumber": 109831860, - "cumulativeGasUsed": "27967278", + "blockNumber": 110049098, + "cumulativeGasUsed": "2913438", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0x8e3d3c6cee0d946dec6ad0cb6ff3f9c902771d51868ec082a9aa440bd84685ad\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610163806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2, address router) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n s.stargateRouter = IStargateRouter(router);\\n }\\n}\\n\",\"keccak256\":\"0xd9e7e1bf8fc13c1490d02df612a04e30f3ad189728f67888d4ab6ad884e30d43\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/KittyFacet.json b/packages/hardhat/deployments/optimism/KittyFacet.json index c1a0dacf..88861712 100644 --- a/packages/hardhat/deployments/optimism/KittyFacet.json +++ b/packages/hardhat/deployments/optimism/KittyFacet.json @@ -1,5 +1,5 @@ { - "address": "0x208F4e08017b66AFCFA14Be44e85ee21bB025707", + "address": "0x56b990b4909E916E1dA74294D8b67ED045402313", "abi": [ { "inputs": [], @@ -122,28 +122,28 @@ "type": "function" } ], - "transactionHash": "0xd5705c9337ad33f195b5f8b028d6dddb36c4bf7bbc18799f24a10b540535aa40", + "transactionHash": "0x553e8cd80d4af19e846751e5a3d52812bcf195749d6c40ded560b7c1ee0f7dda", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x208F4e08017b66AFCFA14Be44e85ee21bB025707", - "transactionIndex": 4, + "contractAddress": "0x56b990b4909E916E1dA74294D8b67ED045402313", + "transactionIndex": 1, "gasUsed": "825217", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x55c077ab2355d4baf950687160bb226dc0dc8b5e7e3942269679e4095604b1fc", - "transactionHash": "0xd5705c9337ad33f195b5f8b028d6dddb36c4bf7bbc18799f24a10b540535aa40", + "blockHash": "0x07dc1449342b910305bdab80484a9dd5872a1f6b7bade2250ff470711ecafb94", + "transactionHash": "0x553e8cd80d4af19e846751e5a3d52812bcf195749d6c40ded560b7c1ee0f7dda", "logs": [], - "blockNumber": 109755139, - "cumulativeGasUsed": "1713058", + "blockNumber": 110048966, + "cumulativeGasUsed": "872118", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5cd8d244f7163e4db8c139c06517a410", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b2dbdcc0b6941fae124c7dae9af5f1726bb6c522b1bb92b1dede393f5927230\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0xcf24bb7018a505bbb0f35146f9793f6ef407ce11a998817aff570a66e7848b98\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0xa4b787bb171f2fd5cba3310a8cee7eee32e4ab06f5902a6fcd62273c551115ed\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3abf20697535d8feceedd82cbde3105a9e6a6c6ddfc75532a588bca369ab520d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0x6cf80a254d66f174fc82fdc474aea1b71dad36e3a6cf0e2353e2298e04041ce2\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0x9b80854a259f0f4fe4e72968297f1d28afe40d9c62a6d59df007568be79f8b02\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/OwnershipFacet.json b/packages/hardhat/deployments/optimism/OwnershipFacet.json index 402c424e..0f819aab 100644 --- a/packages/hardhat/deployments/optimism/OwnershipFacet.json +++ b/packages/hardhat/deployments/optimism/OwnershipFacet.json @@ -1,5 +1,5 @@ { - "address": "0x2B7327b37F48fEa6D2063C9c03fC7250ecA56955", + "address": "0x8A895ecbE10Aa09441aA19D2c0DB00F5DCF72481", "abi": [ { "anonymous": false, @@ -47,28 +47,28 @@ "type": "function" } ], - "transactionHash": "0x14095ccf88f976ea0e7ac76aa094a5df15a41ae46c266340224a48ef91740e5d", + "transactionHash": "0x56f119985ee4b3b90bef9087b0bd5c1d657ed4ead4f531653e1956c4ec6faf27", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x2B7327b37F48fEa6D2063C9c03fC7250ecA56955", - "transactionIndex": 3, + "contractAddress": "0x8A895ecbE10Aa09441aA19D2c0DB00F5DCF72481", + "transactionIndex": 4, "gasUsed": "209234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa78e4387eabdb3491e6eb6bbee116fb384ec258950c807d3e6b33808a9bc1cf8", - "transactionHash": "0x14095ccf88f976ea0e7ac76aa094a5df15a41ae46c266340224a48ef91740e5d", + "blockHash": "0x056a4511503285c2490496ff5d6592a5b615508434aa00f9c133f4856ce45024", + "transactionHash": "0x56f119985ee4b3b90bef9087b0bd5c1d657ed4ead4f531653e1956c4ec6faf27", "logs": [], - "blockNumber": 109755136, - "cumulativeGasUsed": "671220", + "blockNumber": 110048956, + "cumulativeGasUsed": "3197331", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5cd8d244f7163e4db8c139c06517a410", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0x2836ab3ca2aebaaffbafed73912c31012d34b0a20860394fd7050199401de018\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0xd14213dfd60c9476041ad22fcb96d4d81cda561979c24befa9de88220dae51d2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", "devdoc": { "events": { "OwnershipTransferred(address,address)": { diff --git a/packages/hardhat/deployments/optimism/UniV2LikeFacet.json b/packages/hardhat/deployments/optimism/UniV2LikeFacet.json index 2561e44a..6edafc40 100644 --- a/packages/hardhat/deployments/optimism/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/optimism/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x7F2970FF7658d334ff5F4F01a7Ec1b76c797fDEd", + "address": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0xcfb3b54e742c434c8edda19e949545d1fe635161768c1ca8a319ae09c59d1c9a", + "transactionHash": "0xb01434ad875bcf096e86f071051b532c896ce5d36fb2a2e072e8064828816611", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x7F2970FF7658d334ff5F4F01a7Ec1b76c797fDEd", - "transactionIndex": 10, - "gasUsed": "2056445", + "contractAddress": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", + "transactionIndex": 1, + "gasUsed": "2056433", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbc46e9c51c8cf775daf980dea20c0b95030c556b49bf8b446d7fa607e8bfed77", - "transactionHash": "0xcfb3b54e742c434c8edda19e949545d1fe635161768c1ca8a319ae09c59d1c9a", + "blockHash": "0xb17ef2573dcf8ea8bc3347629bcce52970478b16c6553e6f19969617def838d9", + "transactionHash": "0xb01434ad875bcf096e86f071051b532c896ce5d36fb2a2e072e8064828816611", "logs": [], - "blockNumber": 109831841, - "cumulativeGasUsed": "3844951", + "blockNumber": 110048977, + "cumulativeGasUsed": "2120446", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56e7341e6a317f670cc3df2ee1e18b3a47c8e11f302db67b787aba91007d2280\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xcf11728bd04fa6c509bfa1093d6e6f9490a1b2fb41a94144d13d0c0abe3db24a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xea45669f18797f167c70a3fc6ee194fa38fea7a14d310045083d2b64bb88397d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x8dec0c768b0e3875e1e59d241435bcdf88de646aa674ad20c26204d166d6acc9\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/UniV3Callback.json b/packages/hardhat/deployments/optimism/UniV3Callback.json index cea3ba01..3138fc8b 100644 --- a/packages/hardhat/deployments/optimism/UniV3Callback.json +++ b/packages/hardhat/deployments/optimism/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0xb496D9091eA43e66e9d2ACa5CAd7736AF6C39367", + "address": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", "abi": [ { "inputs": [], @@ -53,28 +53,28 @@ "type": "function" } ], - "transactionHash": "0xa9cef2e00dd03073f933035490b7efed81c99e7801ca82e93e40ba3f1232f207", + "transactionHash": "0x8e9d69ddcef494cdcefec6d97e827898af01b86cadaa4b204d398c0043c68988", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xb496D9091eA43e66e9d2ACa5CAd7736AF6C39367", - "transactionIndex": 4, + "contractAddress": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", + "transactionIndex": 3, "gasUsed": "480236", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xb901753eee1ffa27d31f47ad960e1caf57dfb61e6f9c39b185c6a4cdeba31bca", - "transactionHash": "0xa9cef2e00dd03073f933035490b7efed81c99e7801ca82e93e40ba3f1232f207", + "blockHash": "0x6e3e436e92ef19613a25a83b473bfbbd444f4f5261940b0fdc9c351280ec064c", + "transactionHash": "0x8e9d69ddcef494cdcefec6d97e827898af01b86cadaa4b204d398c0043c68988", "logs": [], - "blockNumber": 109831844, - "cumulativeGasUsed": "2822480", + "blockNumber": 110048985, + "cumulativeGasUsed": "854577", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/UniV3Like.json b/packages/hardhat/deployments/optimism/UniV3Like.json index d7709e90..73a73ff0 100644 --- a/packages/hardhat/deployments/optimism/UniV3Like.json +++ b/packages/hardhat/deployments/optimism/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0xDb2Abb67DEe0479888d54F649eb6419dD2AE0702", + "address": "0x61f07f3BA9ba01B500947E10531f9F42706E991c", "abi": [ { "inputs": [], @@ -219,28 +219,28 @@ "type": "function" } ], - "transactionHash": "0xe5853b4af75577cf7861cb83c79acd702690d0ca0b72f994a95d11dc9cdfa723", + "transactionHash": "0xbdb7f3b29125f195fc17851d77841b49d0cab9e0ed02d3833e5067740abca2b9", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xDb2Abb67DEe0479888d54F649eb6419dD2AE0702", - "transactionIndex": 2, + "contractAddress": "0x61f07f3BA9ba01B500947E10531f9F42706E991c", + "transactionIndex": 5, "gasUsed": "1989150", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdc79928adf30a376dbcf3a3d79a3b911eab36a9e253a027a2de8e32584079e2d", - "transactionHash": "0xe5853b4af75577cf7861cb83c79acd702690d0ca0b72f994a95d11dc9cdfa723", + "blockHash": "0x3e5b99b49c62aba655aaba402ce4aa9b7060701b4bdfda7933684766e0f7f948", + "transactionHash": "0xbdb7f3b29125f195fc17851d77841b49d0cab9e0ed02d3833e5067740abca2b9", "logs": [], - "blockNumber": 109831847, - "cumulativeGasUsed": "2228733", + "blockNumber": 110048995, + "cumulativeGasUsed": "4298562", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89bc1011edc38e6b0575be8b7f43aa2530bff8eaeff5da0ad1f479da30b0a84\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x3d5f724620e8dffd077b86613050bca34d60dab1288090558a63db18c8a8b9b1\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24d951973c414bf7384ab3c8862934f4ea125ba750c0f15f804325faa79a6a6c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xec1f28bdd5499b3065bebb77fa28e1a5b03dd07d22cb0273987f8f3dc9796096\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/WarpLink.json b/packages/hardhat/deployments/optimism/WarpLink.json index 7800300d..ad734c7a 100644 --- a/packages/hardhat/deployments/optimism/WarpLink.json +++ b/packages/hardhat/deployments/optimism/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0x23AB6D003341883D6D3f31192702F5B35995596F", + "address": "0xF83C7f55c2f1D2c1e83b539d5C925E4C0cC49435", "abi": [ { "inputs": [], @@ -16,11 +16,6 @@ "name": "DeadlineExpired", "type": "error" }, - { - "inputs": [], - "name": "EthNotSupportedForWarp", - "type": "error" - }, { "inputs": [ { @@ -34,17 +29,17 @@ }, { "inputs": [], - "name": "InconsistentPartPayerOut", + "name": "IllegalJumpInSplit", "type": "error" }, { "inputs": [], - "name": "InconsistentPartTokenOut", + "name": "InconsistentPartPayerOut", "type": "error" }, { "inputs": [], - "name": "IncorrectEthValue", + "name": "InconsistentPartTokenOut", "type": "error" }, { @@ -54,261 +49,63 @@ }, { "inputs": [], - "name": "InsufficientOutputAmount", + "name": "InsufficientEthValue", "type": "error" }, { "inputs": [], - "name": "InsufficientTokensDelivered", + "name": "InsufficientOutputAmount", "type": "error" }, { "inputs": [], - "name": "NotEnoughParts", + "name": "InsufficientTokensDelivered", "type": "error" }, { "inputs": [], - "name": "UnexpectedPayerForWrap", + "name": "JumpMustBeLastCommand", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForUnwrap", + "name": "NativeTokenNotSupported", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForWrap", + "name": "NotEnoughParts", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenOut", + "name": "UnexpectedPayerForWrap", "type": "error" }, { "inputs": [], - "name": "UnexpectedValueAndTokenCombination", + "name": "UnexpectedTokenForUnwrap", "type": "error" }, { "inputs": [], - "name": "UnhandledCommand", + "name": "UnexpectedTokenForWrap", "type": "error" }, { "inputs": [], - "name": "UnhandledPoolKind", + "name": "UnexpectedTokenOut", "type": "error" }, { "inputs": [], - "name": "COMMAND_TYPE_SPLIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_UNWRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeSplit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeUnwrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpCurveExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledCommand", + "type": "error" }, { "inputs": [], - "name": "commandTypeWrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledPoolKind", + "type": "error" }, { "inputs": [ @@ -393,28 +190,28 @@ "type": "function" } ], - "transactionHash": "0xfaea2933b43d68bd682a73f73e1a99daca4bfece1e043cc8c3e51341c1c09ee7", + "transactionHash": "0x142fdc009df5ff81b98c235dc729a879253c2001cb24089a19b3d6d6ed0665b8", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x23AB6D003341883D6D3f31192702F5B35995596F", - "transactionIndex": 6, - "gasUsed": "3602947", + "contractAddress": "0xF83C7f55c2f1D2c1e83b539d5C925E4C0cC49435", + "transactionIndex": 5, + "gasUsed": "3923320", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe9147f7fe04b4da791da7f641bbc61e0601abd02261adf9e2000b610487017fa", - "transactionHash": "0xfaea2933b43d68bd682a73f73e1a99daca4bfece1e043cc8c3e51341c1c09ee7", + "blockHash": "0xea84f82aad5643e4cb221b12129cf4308c37816b25c93de7f656418ccc32ac41", + "transactionHash": "0x142fdc009df5ff81b98c235dc729a879253c2001cb24089a19b3d6d6ed0665b8", "logs": [], - "blockNumber": 109831850, - "cumulativeGasUsed": "5046133", + "blockNumber": 110049007, + "cumulativeGasUsed": "5006788", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthNotSupportedForWarp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedValueAndTokenCombination\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_SPLIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_UNWRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeSplit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeUnwrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpCurveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract WarpLink is IWarpLink {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct TransientState {\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n }\\n\\n uint256 public constant COMMAND_TYPE_WRAP = 1;\\n uint256 public constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 public constant COMMAND_TYPE_SPLIT = 4;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 public constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n\\n function commandTypeWrap() external pure returns (uint256) {\\n return COMMAND_TYPE_WRAP;\\n }\\n\\n function commandTypeUnwrap() external pure returns (uint256) {\\n return COMMAND_TYPE_UNWRAP;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeSplit() external pure returns (uint256) {\\n return COMMAND_TYPE_SPLIT;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn != address(0)) {\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n TransientState memory t;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (msg.value == 0) {\\n if (params.tokenIn == address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n } else {\\n if (params.tokenIn != address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd9e99e7f5322f064977ea54517ad3889c4b74b1828d18c79e0490e06e2295a09\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedValueAndTokenCombination();\\n error UnexpectedPayerForWrap();\\n error EthNotSupportedForWarp();\\n error DeadlineExpired();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n\\n function commandTypeWrap() external pure returns (uint256);\\n\\n function commandTypeUnwrap() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeSplit() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa25e901022a1fc4f1bddb4e10cdce3a8963172ff1a8af9f4a2000ab0959876e7\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6c564dca55e92d9ee1c546a75a68d4e7c8799773f59f2aab4ea72cc70e601dff\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061409b806100206000396000f3fe60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "df6263755b6a66e75866b356448256e7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IllegalJumpInSplit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JumpMustBeLastCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nabstract contract WarpLinkCommandTypes {\\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\\n}\\n\\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct JumpStargateParams {\\n uint16 dstChainId;\\n uint256 srcPoolId;\\n uint256 dstPoolId;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n /**\\n * 0 or 1\\n */\\n uint256 jumped;\\n /**\\n * The amount of native value not spent. The native value starts off as\\n * `msg.value - params.amount` and is decreased by spending money on jumps.\\n *\\n * Any leftover native value is returned to `msg.sender`\\n */\\n uint256 nativeValueRemaining;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (tPart.jumped == 1) {\\n revert IllegalJumpInSplit();\\n }\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\n *\\n * The token must not be ETH (0)\\n *\\n * After this operation, the token will be unchanged and `t.amount` will\\n * be how much was sent. `t.jumped` will be set to `1` to indicate\\n * that no more commands should be run\\n *\\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\\n * because only `t.token` can be moved by Stargate.\\n *\\n * This command must not run inside of a split.\\n *\\n * A bridge fee must be paid in the native token. This fee is determined with\\n * `IStargateRouter.quoteLayerZeroFee`\\n *\\n * The value for `t.token` remains the same and is not chained.\\n *\\n * Params are read from the stream as:\\n * - dstChainId (uint16)\\n * - srcPoolId (uint8)\\n * - dstPoolId (uint8)\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n // NOTE: There is a WETH pool\\n revert NativeTokenNotSupported();\\n }\\n\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibKitty.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens\\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\\n }\\n\\n t.jumped = 1;\\n\\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // Max 5% slippage\\n _minAmountLD: (t.amount * 95) / 100,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(t.paramRecipient),\\n _payload: ''\\n });\\n\\n t.nativeValueRemaining = 0;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\\n if (commandIndex != commandCount - 1) {\\n revert JumpMustBeLastCommand();\\n }\\n\\n t = processJumpStargate(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramRecipient = params.recipient;\\n t.paramAmountOut = params.amountOut;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (params.tokenIn == address(0)) {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n t.nativeValueRemaining = msg.value - params.amountIn;\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n } else {\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n\\n t.nativeValueRemaining = msg.value;\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n if (t.jumped == 1) {\\n // The coins have jumped away from this chain. Fees were collected before the jump\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0be7a956a725d437c18e3bc2a96f09804a20c04d17feac9ac895b503152c13e2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error InsufficientEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedPayerForWrap();\\n error NativeTokenNotSupported();\\n error DeadlineExpired();\\n error IllegalJumpInSplit();\\n error JumpMustBeLastCommand();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n}\\n\",\"keccak256\":\"0x9242d5352942101b05bea1dcaea4b057473c4c2ae65214618f5361a18e194daa\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1c4eccca88e3487c6b6663ce51b77ea778e91b801373223e998fe96e2fff1750\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50614669806100206000396000f3fe60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/optimism/solcInputs/025166ddb0f771753ceec554ac05c5f7.json b/packages/hardhat/deployments/optimism/solcInputs/025166ddb0f771753ceec554ac05c5f7.json new file mode 100644 index 00000000..d03365ab --- /dev/null +++ b/packages/hardhat/deployments/optimism/solcInputs/025166ddb0f771753ceec554ac05c5f7.json @@ -0,0 +1,161 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and the amount will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * This command cannot run inside of a split\n *\n * No more commands should execute after this command since the tokens\n * have all left the chain\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * IStargateRouter.quoteLayerZeroFee\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint256)\n * - dstPoolId (uint256)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n // TODO: Make a new error or rename the existing\n revert EthNotSupportedForWarp();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // The value for `t.token` remains the same and is not chained. It is possible that the user\n // has constructed a command where the srcPoolId is not of the token t.token. This should not\n // be dangerous because only `t.token` is allowed to be transferred\n\n // Collect fees\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: uint16(params.dstChainId),\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // TODO: If the min amount is not met, is the tx reverted or is this refunded?\n _minAmountLD: 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encode(uint256(uint160(t.paramRecipient))),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2, address router) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n s.stargateRouter = IStargateRouter(router);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/optimism/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json b/packages/hardhat/deployments/optimism/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json new file mode 100644 index 00000000..d3c23a0d --- /dev/null +++ b/packages/hardhat/deployments/optimism/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json @@ -0,0 +1,191 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "contracts/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\n\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\n// The EIP-2535 Diamond standard requires these functions.\n\ncontract DiamondLoupeFacet is IDiamondLoupe {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; i++) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n }\n}\n" + }, + "contracts/facets/KittyFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IKitty} from '../interfaces/IKitty.sol';\n\ncontract KittyFacet is IKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n error InsufficientOwnerBalance(uint256 available);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\n LibKitty.State storage s = LibKitty.state();\n\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\n uint256 length = tokenSet.length();\n\n tokens_ = new address[](length);\n\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\n }\n }\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\n LibKitty.State storage s = LibKitty.state();\n\n return s.partnerBalances[partner][token];\n }\n\n function partnerWithdraw(address token) external {\n LibKitty.State storage s = LibKitty.state();\n\n uint256 balance = s.partnerBalances[msg.sender][token];\n\n if (balance > 0) {\n s.partnerBalances[msg.sender][token] = 0;\n s.partnerBalancesTotal[token] -= balance;\n\n emit PartnerWithdraw(msg.sender, token, balance);\n\n if (token == address(0)) {\n // NOTE: Control transfered to untrusted address\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n // NOTE: The token is not removed from the partner's token set\n IERC20(token).safeTransfer(msg.sender, balance);\n }\n }\n }\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\n LibDiamond.enforceIsContractOwner();\n\n LibKitty.State storage s = LibKitty.state();\n\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\n\n uint256 balance = token == address(0)\n ? address(this).balance\n : IERC20(token).balanceOf(address(this));\n\n uint256 available = balance - partnerBalanceTotal;\n\n if (amount > available) {\n revert InsufficientOwnerBalance(available);\n }\n\n if (token == address(0)) {\n // Send ETH\n (bool sent, ) = to.call{value: amount}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(token).safeTransfer(to, amount);\n }\n }\n}\n" + }, + "contracts/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IERC173} from '../interfaces/IERC173.sol';\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct TransientState {\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn != address(0)) {\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n TransientState memory t;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (msg.value == 0) {\n if (params.tokenIn == address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n } else {\n if (params.tokenIn != address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/DiamondMultiInit.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\n\ncontract DiamondMultiInit {\n // This function is provided in the third parameter of the `diamondCut` function.\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\n\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\n if (_addresses.length != _calldata.length) {\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\n }\n for (uint i; i < _addresses.length; i++) {\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/init/InitUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitUniV2Router {\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n if (!s.isInitialized) {\n s.isInitialized = true;\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\n s.weth = IWETH(s.uniswapV2router02.WETH());\n }\n\n s.uniswapV2Factory = uniswapV2Factory;\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Factory.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" + }, + "contracts/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/IKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\n\ninterface IKitty {\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\n\n function partnerWithdraw(address token) external;\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedValueAndTokenCombination();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/SifiDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from './libraries/LibDiamond.sol';\nimport {IDiamondCut} from './interfaces/IDiamondCut.sol';\nimport {IDiamondLoupe} from './interfaces/IDiamondLoupe.sol';\n\ncontract SifiDiamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), '');\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), 'Diamond: Function does not exist');\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n receive() external payable {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/optimism/solcInputs/df6263755b6a66e75866b356448256e7.json b/packages/hardhat/deployments/optimism/solcInputs/df6263755b6a66e75866b356448256e7.json new file mode 100644 index 00000000..958f2b3a --- /dev/null +++ b/packages/hardhat/deployments/optimism/solcInputs/df6263755b6a66e75866b356448256e7.json @@ -0,0 +1,119 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and `t.amount` will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\n * because only `t.token` can be moved by Stargate.\n *\n * This command must not run inside of a split.\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * `IStargateRouter.quoteLayerZeroFee`\n *\n * The value for `t.token` remains the same and is not chained.\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint8)\n * - dstPoolId (uint8)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n revert NativeTokenNotSupported();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // Max 5% slippage\n _minAmountLD: (t.amount * 95) / 100,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(t.paramRecipient),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error NativeTokenNotSupported();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/polygon/Curve.json b/packages/hardhat/deployments/polygon/Curve.json index 12753e1e..4766c07b 100644 --- a/packages/hardhat/deployments/polygon/Curve.json +++ b/packages/hardhat/deployments/polygon/Curve.json @@ -1,5 +1,5 @@ { - "address": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", + "address": "0x162608BE0559185Aa9481B7b86708965afb567cF", "abi": [ { "inputs": [], @@ -141,44 +141,44 @@ "type": "function" } ], - "transactionHash": "0x47db6b5e35c90995d03739fac3433f37eb0e7a48186bca44040029900c3384dc", + "transactionHash": "0xc0085087720a378bbad26b5f40b7ba310e9d90762f1e904b5e4e05af970c3d31", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x2336c6F46ba45C97B950E008684b7af6e329Bf7B", - "transactionIndex": 131, + "contractAddress": "0x162608BE0559185Aa9481B7b86708965afb567cF", + "transactionIndex": 35, "gasUsed": "1277511", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", - "blockHash": "0x32a7069acb738a78b4657122bff0a42842faa9395df6997152ba6d0546717341", - "transactionHash": "0x47db6b5e35c90995d03739fac3433f37eb0e7a48186bca44040029900c3384dc", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000120000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0x945a069d7a99e3b0db654d38f74987a328f0bb6027e0030f7558fcaa0e6d7899", + "transactionHash": "0xc0085087720a378bbad26b5f40b7ba310e9d90762f1e904b5e4e05af970c3d31", "logs": [ { - "transactionIndex": 131, - "blockNumber": 47792848, - "transactionHash": "0x47db6b5e35c90995d03739fac3433f37eb0e7a48186bca44040029900c3384dc", + "transactionIndex": 35, + "blockNumber": 47996549, + "transactionHash": "0xc0085087720a378bbad26b5f40b7ba310e9d90762f1e904b5e4e05af970c3d31", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" ], - "data": "0x000000000000000000000000000000000000000000000000005b788796b794340000000000000000000000000000000000000000000000054601112fd3f6d217000000000000000000000000000000000000000000025a3b8c7d36291998e0b800000000000000000000000000000000000000000000000545a598a83d3f3de3000000000000000000000000000000000000000000025a3b8cd8aeb0b05074ec", - "logIndex": 477, - "blockHash": "0x32a7069acb738a78b4657122bff0a42842faa9395df6997152ba6d0546717341" + "data": "0x00000000000000000000000000000000000000000000000000018b31c60cd6380000000000000000000000000000000000000000000000053b1f4ade6d03f1310000000000000000000000000000000000000000000013e6b420aec44996613e0000000000000000000000000000000000000000000000053b1dbfaca6f71af90000000000000000000000000000000000000000000013e6b42239f60fa33776", + "logIndex": 139, + "blockHash": "0x945a069d7a99e3b0db654d38f74987a328f0bb6027e0030f7558fcaa0e6d7899" } ], - "blockNumber": 47792848, - "cumulativeGasUsed": "17756435", + "blockNumber": 47996549, + "cumulativeGasUsed": "7339806", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26a236ab658af7341bd585a6fd11474bb627ba050aca1c08532cd29c72d314c9\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x377723b233f7e22e77f9b0da81d8fb8f78d5adcdb6bb7817f06e602dea6f182e\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212202e23c2f55a13a2133ed05917bccad6de3e636a54b3f7392d29a627d265fb162164736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexIn\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"tokenIndexOut\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"kind\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"underlying\",\"type\":\"bool\"}],\"internalType\":\"struct ICurve.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"curveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"Swaps for Curve pools The pools are not trusted to deliver the correct amount of tokens, so the router verifies this.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/Curve.sol\":\"Curve\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/Curve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {ICurve} from '../interfaces/ICurve.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * Swaps for Curve pools\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n */\\ncontract Curve is ICurve {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (params.tokenIn != address(0)) {\\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to address(this)\\n LibWarp.state().permit2.transferFrom(\\n msg.sender,\\n address(this),\\n (uint160)(params.amountIn),\\n params.tokenIn\\n );\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: msg.value,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\\n dx: params.amountIn,\\n // NOTE: There is no need to set a min out since the balance is verified\\n min_dy: 0\\n });\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb8f29211d45827b00c6c594b8f0b68517a33881f55d8988a06d0721df488ce12\",\"license\":\"MIT\"},\"contracts/interfaces/ICurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface ICurve {\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint48 deadline;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n function curveExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x7439d7d6a66ec29616591dcfe8252bd92ec4852f58edcfb9b1e7102d1d43b74c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061164d806100206000396000f3fe60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c80631940a5aa14610023575b600080fd5b610036610031366004611225565b610048565b60405190815260200160405180910390f35b600082610120015165ffffffffffff16421115610091576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015173ffffffffffffffffffffffffffffffffffffffff161560008161014f576101008501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014a9190611365565b610151565b475b60e086015190915073ffffffffffffffffffffffffffffffffffffffff1615610364576060850151855160e08701516101a29273ffffffffffffffffffffffffffffffffffffffff90911691610594565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e11546040805160e0808201835288015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528951821660808401526101208a01805165ffffffffffff90811660a08601528a35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b5709133919061024b9089018961137e565b6040518563ffffffff1660e01b815260040161026a94939291906113ea565b600060405180830381600087803b15801561028457600080fd5b505af1158015610298573d6000803e3d6000fd5b505050506102c37f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1090565b60010154855160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b15801561034b57600080fd5b505af115801561035f573d6000803e3d6000fd5b505050505b610391856101800151866101a001518760600151348961014001518a61016001518b600001516000610708565b600082610432576101008601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042d9190611365565b610434565b475b905061044082826114db565b935061045486602001518760a00151610a9d565b84101561048d576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ab8660c001518761010001518860800151896020015188610acd565b93508215610557576000866040015173ffffffffffffffffffffffffffffffffffffffff168560405160006040518083038185875af1925050503d8060008114610511576040519150601f19603f3d011682016040523d82523d6000602084013e610516565b606091505b5050905080610551576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061058b565b61058b86604001518588610100015173ffffffffffffffffffffffffffffffffffffffff16610b8e9092919063ffffffff16565b50505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526106208482610be9565b6107025760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526106f89085907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610caa565b6107028482610caa565b50505050565b8760ff166001036108365786156107c1576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b5050505050610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161078a565b8760ff16600203610976578615610901576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156108d6573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906108fb9190611365565b50610a93565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016108b8565b8760ff16600303610a615786156109f4576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016108b8565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016108b8565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b6000612710610aac83826114ee565b610aba9061ffff1685611510565b610ac49190611527565b90505b92915050565b60006107d061ffff85161115610b18576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610b2a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff891615610b645760646032840204610b67565b60005b9050808303838214610b7f57610b7f8a8a8484610db9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610be49084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610676565b505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051610c139190611586565b6000604051808303816000865af19150503d8060008114610c50576040519150601f19603f3d011682016040523d82523d6000602084013e610c55565b606091505b5091509150818015610c7f575080511580610c7f575080806020019051810190610c7f91906115a2565b8015610ca1575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000610d0c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610ebe9092919063ffffffff16565b9050805160001480610d2d575080806020019051810190610d2d91906115a2565b610be4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b0f565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615610e295773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020610e279085610ed5565b505b610e338186610ed5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6060610ecd8484600085610ef7565b949350505050565b6000610ac48373ffffffffffffffffffffffffffffffffffffffff8416611010565b606082471015610f89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b0f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610fb29190611586565b60006040518083038185875af1925050503d8060008114610fef576040519150601f19603f3d011682016040523d82523d6000602084013e610ff4565b606091505b50915091506110058783838761105f565b979650505050505050565b600081815260018301602052604081205461105757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ac7565b506000610ac7565b606083156110f55782516000036110ee5773ffffffffffffffffffffffffffffffffffffffff85163b6110ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b0f565b5081610ecd565b610ecd838381511561110a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0f91906115c6565b6040516101c0810167ffffffffffffffff81118282101715611189577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b803573ffffffffffffffffffffffffffffffffffffffff811681146111b357600080fd5b919050565b803561ffff811681146111b357600080fd5b803565ffffffffffff811681146111b357600080fd5b803560ff811681146111b357600080fd5b80151581146111ff57600080fd5b50565b80356111b3816111f1565b60006040828403121561121f57600080fd5b50919050565b6000808284036101e081121561123a57600080fd5b6101c08082121561124a57600080fd5b61125261113e565b9150843582526020850135602083015261126e6040860161118f565b604083015261127f6060860161118f565b6060830152611290608086016111b8565b60808301526112a160a086016111b8565b60a08301526112b260c0860161118f565b60c08301526112c360e0860161118f565b60e08301526101006112d681870161118f565b908301526101206112e88682016111ca565b908301526101406112fa8682016111e0565b9083015261016061130c8682016111e0565b9083015261018061131e8682016111e0565b908301526101a0611330868201611202565b9083015290925083013567ffffffffffffffff81111561134f57600080fd5b61135b8582860161120d565b9150509250929050565b60006020828403121561137757600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126113b357600080fd5b83018035915067ffffffffffffffff8211156113ce57600080fd5b6020019150368190038213156113e357600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ac757610ac76114ac565b61ffff828116828216039080821115611509576115096114ac565b5092915050565b8082028115828204841417610ac757610ac76114ac565b60008261155d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b8381101561157d578181015183820152602001611565565b50506000910152565b60008251611598818460208701611562565b9190910192915050565b6000602082840312156115b457600080fd5b81516115bf816111f1565b9392505050565b60208152600082518060208401526115e5816040850160208701611562565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212200481b98f8102cb8da0c3c9a8eebc9f4a6d39568ce42d44c0f384e363ad07881b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/DiamondCutFacet.json b/packages/hardhat/deployments/polygon/DiamondCutFacet.json index c4e08473..d153d3f4 100644 --- a/packages/hardhat/deployments/polygon/DiamondCutFacet.json +++ b/packages/hardhat/deployments/polygon/DiamondCutFacet.json @@ -1,5 +1,5 @@ { - "address": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", + "address": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", "abi": [ { "inputs": [ @@ -100,44 +100,44 @@ "type": "function" } ], - "transactionHash": "0x050b08d5ae47df6da9c6f613428d1a844760857551d910ad37ad2485fab3011d", + "transactionHash": "0xc1a97a0efdd5929423f04720dd6007dfd8c305f975e3faf889982ee2cae3b03f", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x777e04694B07a7A7C0C38260477f301b9a2AF9Be", - "transactionIndex": 93, + "contractAddress": "0x96e7dDeD1549C02aA80Fcb77861C32591B273f5e", + "transactionIndex": 117, "gasUsed": "1562880", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000120000000000000000000000000000000000000000000200000000000000000000000000100000", - "blockHash": "0x2c5dac53b4630c655f4fd5c4e7334c91580d6081d854437b6c3f6a24dc2130d3", - "transactionHash": "0x050b08d5ae47df6da9c6f613428d1a844760857551d910ad37ad2485fab3011d", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0xb8d02d7fb11b027f46e5876bc7e372f30e67a88d107e11be920445ab2a50683f", + "transactionHash": "0xc1a97a0efdd5929423f04720dd6007dfd8c305f975e3faf889982ee2cae3b03f", "logs": [ { - "transactionIndex": 93, - "blockNumber": 47442991, - "transactionHash": "0x050b08d5ae47df6da9c6f613428d1a844760857551d910ad37ad2485fab3011d", + "transactionIndex": 117, + "blockNumber": 47993792, + "transactionHash": "0xc1a97a0efdd5929423f04720dd6007dfd8c305f975e3faf889982ee2cae3b03f", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" ], - "data": "0x00000000000000000000000000000000000000000000000000099a1ab54bb9000000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000008c5764aa678ef8d644c0000000000000000000000000000000000000000000000056bbdc412adc447000000000000000000000000000000000000000000000008c576544093a4d91d4c", - "logIndex": 925, - "blockHash": "0x2c5dac53b4630c655f4fd5c4e7334c91580d6081d854437b6c3f6a24dc2130d3" + "data": "0x000000000000000000000000000000000000000000000000008dc5821c13eb0000000000000000000000000000000000000000000000000543aa0d22f8bf0484000000000000000000000000000000000000000000025c7b986084362a33be57000000000000000000000000000000000000000000000005431c47a0dcab1984000000000000000000000000000000000000000000025c7b98ee49b84647a957", + "logIndex": 888, + "blockHash": "0xb8d02d7fb11b027f46e5876bc7e372f30e67a88d107e11be920445ab2a50683f" } ], - "blockNumber": 47442991, - "cumulativeGasUsed": "28401278", + "blockNumber": 47993792, + "cumulativeGasUsed": "24504602", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x862ac209f7309608ba3e033d6f2e185d82936745ae9eff95d78681bd7c09799a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220866da4ffa9116bb5cf9a3c0e5e8e0f4d031932af48052ffb03da4557722c33d964736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0xfb51534d56cfbfc884869f4c67b3b01fb3303a762418d796feabb78543d289ee\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611b90806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004361003e3660046114ba565b610045565b005b61004d61009e565b61009761005a8587611637565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061016e92505050565b5050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461016c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f657200000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b565b60005b835181101561036457600084828151811061018e5761018e611793565b6020026020010151602001519050600060028111156101af576101af6117c2565b8160028111156101c1576101c16117c2565b0361020f5761020a8583815181106101db576101db611793565b6020026020010151600001518684815181106101f9576101f9611793565b6020026020010151604001516103af565b610351565b6001816002811115610223576102236117c2565b0361026c5761020a85838151811061023d5761023d611793565b60200260200101516000015186848151811061025b5761025b611793565b60200260200101516040015161075e565b6002816002811115610280576102806117c2565b036102c95761020a85838151811061029a5761029a611793565b6020026020010151600001518684815181106102b8576102b8611793565b602002602001015160400151610b1d565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560448201527f74416374696f6e000000000000000000000000000000000000000000000000006064820152608401610163565b508061035c81611820565b915050610171565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610398939291906118c6565b60405180910390a16103aa8282610d10565b505050565b6000815111610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff8316610504576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff8216900361054c5761054c8285610e09565b60005b835181101561009757600084828151811061056c5761056c611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff168015610651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610163565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff0000000000000000000000000000000000000000161790558361074681611a2e565b9450505050808061075690611820565b91505061054f565b60008151116107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff83166108b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608401610163565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600182016020526040812054906bffffffffffffffffffffffff821690036108fb576108fb8285610e09565b60005b835181101561009757600084828151811061091b5761091b611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529186905260409091205490915073ffffffffffffffffffffffffffffffffffffffff9081169087168103610a05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610163565b610a10858284610e98565b7fffffffff000000000000000000000000000000000000000000000000000000008216600081815260208781526040808320805473ffffffffffffffffffffffffffffffffffffffff908116740100000000000000000000000000000000000000006bffffffffffffffffffffffff8c16021782558c168085526001808c0185529285208054938401815585528385206008840401805463ffffffff60079095166004026101000a948502191660e08a901c94909402939093179092559390925287905281547fffffffffffffffffffffffff00000000000000000000000000000000000000001617905583610b0581611a2e565b94505050508080610b1590611820565b9150506108fe565b6000815111610bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608401610163565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c73ffffffffffffffffffffffffffffffffffffffff831615610c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610163565b60005b8251811015610d0a576000838281518110610c9357610c93611793565b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff16610cf5848284610e98565b50508080610d0290611820565b915050610c76565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8216610d2f575050565b610d5182604051806060016040528060288152602001611b0f6028913961140d565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d799190611a59565b600060405180830381855af49150503d8060008114610db4576040519150601f19603f3d011682016040523d82523d6000602084013e610db9565b606091505b509150915081610d0a57805115610dd35780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610163929190611a75565b610e2b81604051806060016040528060248152602001611b376024913961140d565b60028201805473ffffffffffffffffffffffffffffffffffffffff90921660008181526001948501602090815260408220860185905594840183559182529290200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b73ffffffffffffffffffffffffffffffffffffffff8216610f3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610163565b3073ffffffffffffffffffffffffffffffffffffffff831603610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608401610163565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152602084815260408083205473ffffffffffffffffffffffffffffffffffffffff86168452600180880190935290832054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16929161106a91611aac565b90508082146111b15773ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604081208054839081106110ac576110ac611793565b6000918252602080832060088304015473ffffffffffffffffffffffffffffffffffffffff8916845260018a019091526040909220805460079092166004026101000a90920460e01b92508291908590811061110a5761110a611793565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790557fffffffff0000000000000000000000000000000000000000000000000000000092909216825286905260409020805473ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000006bffffffffffffffffffffffff8516021790555b73ffffffffffffffffffffffffffffffffffffffff8416600090815260018601602052604090208054806111e7576111e7611ac5565b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90940193840401805463ffffffff600460078716026101000a0219169055919092557fffffffff00000000000000000000000000000000000000000000000000000000851682528690526040812081905581900361009757600285015460009061128090600190611aac565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260018089016020526040909120015490915080821461136e5760008760020183815481106112cc576112cc611793565b60009182526020909120015460028901805473ffffffffffffffffffffffffffffffffffffffff909216925082918490811061130a5761130a611793565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055929091168152600189810190925260409020018190555b8660020180548061138157611381611ac5565b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff88168252600189810190915260408220015550505050505050565b813b8181610d0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101639190611af4565b803573ffffffffffffffffffffffffffffffffffffffff8116811461146c57600080fd5b919050565b60008083601f84011261148357600080fd5b50813567ffffffffffffffff81111561149b57600080fd5b6020830191508360208285010111156114b357600080fd5b9250929050565b6000806000806000606086880312156114d257600080fd5b853567ffffffffffffffff808211156114ea57600080fd5b818801915088601f8301126114fe57600080fd5b81358181111561150d57600080fd5b8960208260051b850101111561152257600080fd5b6020830197508096505061153860208901611448565b9450604088013591508082111561154e57600080fd5b5061155b88828901611471565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156115be576115be61156c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160b5761160b61156c565b604052919050565b600067ffffffffffffffff82111561162d5761162d61156c565b5060051b60200190565b600061164a61164584611613565b6115c4565b83815260208082019190600586811b86013681111561166857600080fd5b865b8181101561178657803567ffffffffffffffff8082111561168b5760008081fd5b818a019150606082360312156116a15760008081fd5b6116a961159b565b6116b283611448565b815286830135600381106116c65760008081fd5b81880152604083810135838111156116de5760008081fd5b939093019236601f8501126116f557600092508283fd5b8335925061170561164584611613565b83815292871b840188019288810190368511156117225760008081fd5b948901945b8486101561176f5785357fffffffff00000000000000000000000000000000000000000000000000000000811681146117605760008081fd5b82529489019490890190611727565b91830191909152508852505094830194830161166a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611851576118516117f1565b5060010190565b60005b8381101561187357818101518382015260200161185b565b50506000910152565b60008151808452611894816020860160208601611858565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156119f1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8503018652815188850173ffffffffffffffffffffffffffffffffffffffff82511686528482015160038110611978577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b808310156119dc5783517fffffffff0000000000000000000000000000000000000000000000000000000016825292860192600192909201919086019061199a565b509785019795505050908201906001016118ef565b505073ffffffffffffffffffffffffffffffffffffffff8a16908801528681036040880152611a20818961187c565b9a9950505050505050505050565b60006bffffffffffffffffffffffff808316818103611a4f57611a4f6117f1565b6001019392505050565b60008251611a6b818460208701611858565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aa4604083018461187c565b949350505050565b81810381811115611abf57611abf6117f1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000611b07602083018461187c565b939250505056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a264697066735822122098abdcaa3bf12eb737076d094ca3aef7c60db634c9565d33e228ae8fa70971ae64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/polygon/DiamondLoupeFacet.json b/packages/hardhat/deployments/polygon/DiamondLoupeFacet.json index 12dad168..5341e9fe 100644 --- a/packages/hardhat/deployments/polygon/DiamondLoupeFacet.json +++ b/packages/hardhat/deployments/polygon/DiamondLoupeFacet.json @@ -1,5 +1,5 @@ { - "address": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", + "address": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", "abi": [ { "inputs": [ @@ -78,44 +78,44 @@ "type": "function" } ], - "transactionHash": "0xdc1c2bd89cf1bd761af22ebad187ca5aebd79246f4959825d5dc5b8cdffae3d6", + "transactionHash": "0x5306a803d52fcebc2da82c126ac3a2fd9680a3d78524460977af9ecfe7375240", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x1c8B58b5DA3B33F7bBeda432AC22354e00379ad8", - "transactionIndex": 28, + "contractAddress": "0x12Ad749fbdCF48bBc2D4aDcD00f95BA99bd13b63", + "transactionIndex": 102, "gasUsed": "480128", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000002000000000000000000800000000000000000000110000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000080000000000000000000200000000000000000000000000100000", - "blockHash": "0xc5917d6c1bcdb53a14f94d8f930d8e139e19fb5ce8c54ac6fd4f3f0d085b8cb5", - "transactionHash": "0xdc1c2bd89cf1bd761af22ebad187ca5aebd79246f4959825d5dc5b8cdffae3d6", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0x743439578cd9b12df9715241ab6cfdbdca7aa70da3bba04d4e307113293d0ff4", + "transactionHash": "0x5306a803d52fcebc2da82c126ac3a2fd9680a3d78524460977af9ecfe7375240", "logs": [ { - "transactionIndex": 28, - "blockNumber": 47478604, - "transactionHash": "0xdc1c2bd89cf1bd761af22ebad187ca5aebd79246f4959825d5dc5b8cdffae3d6", + "transactionIndex": 102, + "blockNumber": 47994768, + "transactionHash": "0x5306a803d52fcebc2da82c126ac3a2fd9680a3d78524460977af9ecfe7375240", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x00000000000000000000000002f70172f7f490653665c9bfac0666147c8af1f5" + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" ], - "data": "0x000000000000000000000000000000000000000000000000003094b481a27680000000000000000000000000000000000000000000000005693a1d81b879733b000000000000000000000000000000000000000000000049b71c7f0c479e64df000000000000000000000000000000000000000000000005690988cd36d6fcbb000000000000000000000000000000000000000000000049b74d13c0c940db5f", - "logIndex": 2659, - "blockHash": "0xc5917d6c1bcdb53a14f94d8f930d8e139e19fb5ce8c54ac6fd4f3f0d085b8cb5" + "data": "0x000000000000000000000000000000000000000000000000001ca07f4acaba0000000000000000000000000000000000000000000000000542746ac95802df84000000000000000000000000000000000000000000025c7d166cbd0fcf71a8090000000000000000000000000000000000000000000000054257ca4a0d382584000000000000000000000000000000000000000000025c7d16895d8f1a3c6209", + "logIndex": 767, + "blockHash": "0x743439578cd9b12df9715241ab6cfdbdca7aa70da3bba04d4e307113293d0ff4" } ], - "blockNumber": 47478604, - "cumulativeGasUsed": "14895750", + "blockNumber": 47994768, + "cumulativeGasUsed": "24697922", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x912f2287b015cd1568157eb79d48033d8db3be846de4c50691d44ad5dc1a638b\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122017400d99eedea0ccd778263052cc376f8e148def2cf1eb7666b850c95491c27d64736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_functionSelector\",\"type\":\"bytes4\"}],\"name\":\"facetAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"facetAddress_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facetAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"facetAddresses_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_facet\",\"type\":\"address\"}],\"name\":\"facetFunctionSelectors\",\"outputs\":[{\"internalType\":\"bytes4[]\",\"name\":\"facetFunctionSelectors_\",\"type\":\"bytes4[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"facets\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondLoupe.Facet[]\",\"name\":\"facets_\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"facetAddress(bytes4)\":{\"details\":\"If facet is not found return address(0).\",\"params\":{\"_functionSelector\":\"The function selector.\"},\"returns\":{\"facetAddress_\":\"The facet address.\"}},\"facetAddresses()\":{\"returns\":{\"facetAddresses_\":\"facetAddresses_\"}},\"facetFunctionSelectors(address)\":{\"params\":{\"_facet\":\"The facet address.\"},\"returns\":{\"facetFunctionSelectors_\":\"facetFunctionSelectors_\"}},\"facets()\":{\"returns\":{\"facets_\":\"Facet\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"facetAddress(bytes4)\":{\"notice\":\"Gets the facet that supports the given selector.\"},\"facetAddresses()\":{\"notice\":\"Get all the facet addresses used by a diamond.\"},\"facetFunctionSelectors(address)\":{\"notice\":\"Gets all the function selectors provided by a facet.\"},\"facets()\":{\"notice\":\"Gets all facets and their selectors.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/DiamondLoupeFacet.sol\":\"DiamondLoupeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/DiamondLoupeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\\n\\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\\n// The EIP-2535 Diamond standard requires these functions.\\n\\ncontract DiamondLoupeFacet is IDiamondLoupe {\\n // Diamond Loupe Functions\\n ////////////////////////////////////////////////////////////////////\\n /// These functions are expected to be called frequently by tools.\\n //\\n // struct Facet {\\n // address facetAddress;\\n // bytes4[] functionSelectors;\\n // }\\n\\n /// @notice Gets all facets and their selectors.\\n /// @return facets_ Facet\\n function facets() external view override returns (Facet[] memory facets_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n uint256 numFacets = ds.facetAddresses.length;\\n facets_ = new Facet[](numFacets);\\n for (uint256 i; i < numFacets; i++) {\\n address facetAddress_ = ds.facetAddresses[i];\\n facets_[i].facetAddress = facetAddress_;\\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\\n }\\n }\\n\\n /// @notice Gets all the function selectors provided by a facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\\n }\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddresses_ = ds.facetAddresses;\\n }\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(\\n bytes4 _functionSelector\\n ) external view override returns (address facetAddress_) {\\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\\n }\\n}\\n\",\"keccak256\":\"0x5edfd8138efb21086b53df2028f755aae576b00a7193102cca00d14beb025475\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondLoupe.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\n// A loupe is a small magnifying glass used to look at diamonds.\\n// These functions look at diamonds\\ninterface IDiamondLoupe {\\n /// These functions are expected to be called frequently\\n /// by tools.\\n\\n struct Facet {\\n address facetAddress;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Gets all facet addresses and their four byte function selectors.\\n /// @return facets_ Facet\\n function facets() external view returns (Facet[] memory facets_);\\n\\n /// @notice Gets all the function selectors supported by a specific facet.\\n /// @param _facet The facet address.\\n /// @return facetFunctionSelectors_\\n function facetFunctionSelectors(\\n address _facet\\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\\n\\n /// @notice Get all the facet addresses used by a diamond.\\n /// @return facetAddresses_\\n function facetAddresses() external view returns (address[] memory facetAddresses_);\\n\\n /// @notice Gets the facet that supports the given selector.\\n /// @dev If facet is not found return address(0).\\n /// @param _functionSelector The function selector.\\n /// @return facetAddress_ The facet address.\\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\\n}\\n\",\"keccak256\":\"0xb5c017590093a5e7e92dd7340a2b9b74f502a45826cc0ea38700ff2496611994\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806352ef6b2c146100515780637a0ed6271461006f578063adfca15e14610084578063cdffacc6146100a4575b600080fd5b610059610140565b60405161006691906104de565b60405180910390f35b6100776101d2565b6040516100669190610595565b61009761009236600461063d565b6103de565b604051610066919061067a565b61011b6100b236600461068d565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610066565b606060007fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600281018054604080516020808402820181019092528281529394508301828280156101c757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161019c575b505050505091505090565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131e546060907fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c908067ffffffffffffffff811115610232576102326106cf565b60405190808252806020026020018201604052801561027857816020015b6040805180820190915260008152606060208201528152602001906001900390816102505790505b50925060005b818110156103d857600083600201828154811061029d5761029d6106fe565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808583815181106102dd576102dd6106fe565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff928316905290821660009081526001860182526040908190208054825181850281018501909352808352919290919083018282801561039e57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161034b5790505b50505050508583815181106103b5576103b56106fe565b6020026020010151602001819052505080806103d09061072d565b91505061027e565b50505090565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131d602090815260409182902080548351818402810184019094528084526060937fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c93909291908301828280156104d157602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161047e5790505b5050505050915050919050565b6020808252825182820181905260009190848201906040850190845b8181101561052c57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016104fa565b50909695505050505050565b600081518084526020808501945080840160005b8381101561058a5781517fffffffff00000000000000000000000000000000000000000000000000000000168752958201959082019060010161054c565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561062f578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff16845287015187840187905261061c87850182610538565b95880195935050908601906001016105bc565b509098975050505050505050565b60006020828403121561064f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461067357600080fd5b9392505050565b6020815260006106736020830184610538565b60006020828403121561069f57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461067357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2dde89f57f8b9382c8a0199a3434f8428b4c822acace508551125c6917f627264736f6c63430008130033", "devdoc": { "kind": "dev", "methods": { diff --git a/packages/hardhat/deployments/polygon/DiamondMultiInit.json b/packages/hardhat/deployments/polygon/DiamondMultiInit.json index f5c7989d..0770ed65 100644 --- a/packages/hardhat/deployments/polygon/DiamondMultiInit.json +++ b/packages/hardhat/deployments/polygon/DiamondMultiInit.json @@ -1,5 +1,5 @@ { - "address": "0x99B9e8B2E79F511C7d97808A1174Ebe1835b9446", + "address": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", "abi": [ { "inputs": [ @@ -52,44 +52,44 @@ "type": "function" } ], - "transactionHash": "0xe97a42aba739210995dc1cd88caf13ae68b428be39d761461e8aaa3e43cdc722", + "transactionHash": "0xf837971828e95336e14cd639507eb51b909690cfe8021c7ae94deca3a9a44dd2", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x99B9e8B2E79F511C7d97808A1174Ebe1835b9446", - "transactionIndex": 46, + "contractAddress": "0x71e0BD402c5C0B61dE1D224824c551fE0D623065", + "transactionIndex": 82, "gasUsed": "358372", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000020000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0xc6a7d6bffee877bbe9985192216fa74d20196ada63ae73401e41e0a4b2fb733b", - "transactionHash": "0xe97a42aba739210995dc1cd88caf13ae68b428be39d761461e8aaa3e43cdc722", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000800000000800000000000100000000000000000000000000000001000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0xe13c39a4dead8d83c04a6b443639e524e0691e9bf4ce3a706b4120babd6cdb43", + "transactionHash": "0xf837971828e95336e14cd639507eb51b909690cfe8021c7ae94deca3a9a44dd2", "logs": [ { - "transactionIndex": 46, - "blockNumber": 47481546, - "transactionHash": "0xe97a42aba739210995dc1cd88caf13ae68b428be39d761461e8aaa3e43cdc722", + "transactionIndex": 82, + "blockNumber": 47996603, + "transactionHash": "0xf837971828e95336e14cd639507eb51b909690cfe8021c7ae94deca3a9a44dd2", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000959c65b72147faf3450d8b50a0de57e72ffc5e0d" + "0x000000000000000000000000eb4f2a75cac4bbcb4d71c252e4cc80eb80bb3a34" ], - "data": "0x000000000000000000000000000000000000000000000000002dbcc505490c300000000000000000000000000000000000000000000000055458e54ec446b5ce000000000000000000000000000000000000000000000d3816a1de815ccfcde3000000000000000000000000000000000000000000000005542b2889befda99e000000000000000000000000000000000000000000000d3816cf9b466218da13", - "logIndex": 227, - "blockHash": "0xc6a7d6bffee877bbe9985192216fa74d20196ada63ae73401e41e0a4b2fb733b" + "data": "0x0000000000000000000000000000000000000000000000000000e7b8b31d09a000000000000000000000000000000000000000000000000539e11d864800afc3000000000000000000000000000000000000000000000aabd3ed091c32a72d2f00000000000000000000000000000000000000000000000539e035cd94e3a623000000000000000000000000000000000000000000000aabd3edf0d4e5c436cf", + "logIndex": 360, + "blockHash": "0xe13c39a4dead8d83c04a6b443639e524e0691e9bf4ce3a706b4120babd6cdb43" } ], - "blockNumber": 47481546, - "cumulativeGasUsed": "6892432", + "blockNumber": 47996603, + "cumulativeGasUsed": "22833210", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7039f6a07145a76f91a7f976a7f6af7fba83d559a3f895e6c425fe1fbd239fce\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a2646970667358221220afc0ecb2905d86b3c3691ecce015d381dd20213b73ea2d0242431368b68dc06264736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_addressesLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_calldataLength\",\"type\":\"uint256\"}],\"name\":\"AddressAndCalldataLengthDoNotMatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_initializationContractAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"InitializationFunctionReverted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_calldata\",\"type\":\"bytes[]\"}],\"name\":\"multiInit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/DiamondMultiInit.sol\":\"DiamondMultiInit\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/init/DiamondMultiInit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n*\\n* Implementation of a diamond.\\n/******************************************************************************/\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\n\\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\\n\\ncontract DiamondMultiInit {\\n // This function is provided in the third parameter of the `diamondCut` function.\\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\\n\\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\\n if (_addresses.length != _calldata.length) {\\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\\n }\\n for (uint i; i < _addresses.length; i++) {\\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8a6197389eba7856703a1fbabf7ecdd760678fcaf61be646731a14e4f88e80e9\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061058d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e02fa3c14610030575b600080fd5b61004361003e3660046102bf565b610045565b005b82811461008d576040517f7340e16600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b60005b83811015610132576101208585838181106100ad576100ad61032b565b90506020020160208101906100c2919061035a565b8484848181106100d4576100d461032b565b90506020028101906100e69190610397565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013992505050565b8061012a816103fc565b915050610090565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610158575050565b61017a8260405180606001604052806028815260200161053060289139610238565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516101a2919061047f565b600060405180830381855af49150503d80600081146101dd576040519150601f19603f3d011682016040523d82523d6000602084013e6101e2565b606091505b509150915081610232578051156101fc5780518082602001fd5b83836040517f192105d70000000000000000000000000000000000000000000000000000000081526004016100849291906104e5565b50505050565b813b8181610232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610084919061051c565b60008083601f84011261028557600080fd5b50813567ffffffffffffffff81111561029d57600080fd5b6020830191508360208260051b85010111156102b857600080fd5b9250929050565b600080600080604085870312156102d557600080fd5b843567ffffffffffffffff808211156102ed57600080fd5b6102f988838901610273565b9096509450602087013591508082111561031257600080fd5b5061031f87828801610273565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561036c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126103cc57600080fd5b83018035915067ffffffffffffffff8211156103e757600080fd5b6020019150368190038213156102b857600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610454577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60005b8381101561047657818101518382015260200161045e565b50506000910152565b6000825161049181846020870161045b565b9190910192915050565b600081518084526104b381602086016020860161045b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610514604083018461049b565b949350505050565b602081526000610390602083018461049b56fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f6465a26469706673582212207217874a568487a84b449cfcde224e682e91046cff0b82dce5306796edc09e1864736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/InitLibWarp.json b/packages/hardhat/deployments/polygon/InitLibWarp.json index 8d31c028..429b21d1 100644 --- a/packages/hardhat/deployments/polygon/InitLibWarp.json +++ b/packages/hardhat/deployments/polygon/InitLibWarp.json @@ -1,5 +1,5 @@ { - "address": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", + "address": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", "abi": [ { "inputs": [ @@ -12,6 +12,11 @@ "internalType": "address", "name": "permit2", "type": "address" + }, + { + "internalType": "address", + "name": "router", + "type": "address" } ], "name": "init", @@ -20,44 +25,44 @@ "type": "function" } ], - "transactionHash": "0xd798fdb767c33fc330247f042a384015e08c1bfb3bb0bde4da72551ed22c2580", + "transactionHash": "0xe5f610e4ac4c1f300dfd0566771205bd183535daaeeedb78aab269b60665a869", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xe50AE9D11aA38C7fC48D1277D19C096f40c8Bad9", - "transactionIndex": 81, - "gasUsed": "129799", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", - "blockHash": "0x3fb4f1eb86765d1d1794aded2e691cdf9d4cc28b14ce90f0ebe738f8d89789d1", - "transactionHash": "0xd798fdb767c33fc330247f042a384015e08c1bfb3bb0bde4da72551ed22c2580", + "contractAddress": "0xd7f9d9b2245a09457BfbCAE5F39292596C1879E9", + "transactionIndex": 5, + "gasUsed": "143671", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000001000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100020000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000020100000", + "blockHash": "0xd6cd967150026efd8e8b77bbb06b97d86309338f0eae994f5a63d7243bf82c70", + "transactionHash": "0xe5f610e4ac4c1f300dfd0566771205bd183535daaeeedb78aab269b60665a869", "logs": [ { - "transactionIndex": 81, - "blockNumber": 47792855, - "transactionHash": "0xd798fdb767c33fc330247f042a384015e08c1bfb3bb0bde4da72551ed22c2580", + "transactionIndex": 5, + "blockNumber": 47996576, + "transactionHash": "0xe5f610e4ac4c1f300dfd0566771205bd183535daaeeedb78aab269b60665a869", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + "0x000000000000000000000000794e44d1334a56fea7f4df12633b88820d0c5888" ], - "data": "0x000000000000000000000000000000000000000000000000000511be33926b4600000000000000000000000000000000000000000000000544b4e0b4c93c811a000000000000000000000000000000000000000000025a3bd3373ae0eced980c00000000000000000000000000000000000000000000000544afcef695aa15d4000000000000000000000000000000000000000000025a3bd33c4c9f20800352", - "logIndex": 303, - "blockHash": "0x3fb4f1eb86765d1d1794aded2e691cdf9d4cc28b14ce90f0ebe738f8d89789d1" + "data": "0x0000000000000000000000000000000000000000000000000045915ba892daa10000000000000000000000000000000000000000000000053a311afd6150c6f00000000000000000000000000000000000000000000002333baa41a107b5284200000000000000000000000000000000000000000000000539eb89a1b8bdec4f0000000000000000000000000000000000000000000002333befd2fcb04802e3", + "logIndex": 14, + "blockHash": "0xd6cd967150026efd8e8b77bbb06b97d86309338f0eae994f5a63d7243bf82c70" } ], - "blockNumber": 47792855, - "cumulativeGasUsed": "10424976", + "blockNumber": 47996576, + "cumulativeGasUsed": "455658", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n }\\n}\\n\",\"keccak256\":\"0x8e3d3c6cee0d946dec6ad0cb6ff3f9c902771d51868ec082a9aa440bd84685ad\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610163806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f09a401614610030575b600080fd5b6100cf61003e3660046100fa565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054929093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff811681146100f557600080fd5b919050565b6000806040838503121561010d57600080fd5b610116836100d1565b9150610124602084016100d1565b9050925092905056fea26469706673582212207bfdffebdade222d067e9a73381caaab8a3d4b662f9706adfcc4b31f7b9a8eb864736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"permit2\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/init/InitLibWarp.sol\":\"InitLibWarp\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/init/InitLibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\ncontract InitLibWarp {\\n function init(address weth, address permit2, address router) public {\\n LibWarp.State storage s = LibWarp.state();\\n\\n s.weth = IWETH(weth);\\n s.permit2 = IPermit2(permit2);\\n s.stargateRouter = IStargateRouter(router);\\n }\\n}\\n\",\"keccak256\":\"0xd9e7e1bf8fc13c1490d02df612a04e30f3ad189728f67888d4ab6ad884e30d43\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063184b955914610030575b600080fd5b6100ff61003e36600461012a565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e118054938516938216939093179092557f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e128054919093169116179055565b005b803573ffffffffffffffffffffffffffffffffffffffff8116811461012557600080fd5b919050565b60008060006060848603121561013f57600080fd5b61014884610101565b925061015660208501610101565b915061016460408501610101565b9050925092509256fea264697066735822122003fe5816e099df8eb0b7918c86fe4834a0306a56c1274ca72865bd622470b9aa64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/KittyFacet.json b/packages/hardhat/deployments/polygon/KittyFacet.json index 6f594bb9..fff209e4 100644 --- a/packages/hardhat/deployments/polygon/KittyFacet.json +++ b/packages/hardhat/deployments/polygon/KittyFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd153380b0d297eB44984d9D6cB9A4b9Eae03FCc0", + "address": "0xAed6fe85bb7fA0761FfbB9D85cd2E39E5038e7c5", "abi": [ { "inputs": [], @@ -122,44 +122,44 @@ "type": "function" } ], - "transactionHash": "0x34fb010ddd51e165d6adc9cd6a683eac75be8b1ace093eb2a889ec309a8753be", + "transactionHash": "0x906132a4c53f0344b50e321b0637df5c57235590c918becbae4f2499cec0cde7", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd153380b0d297eB44984d9D6cB9A4b9Eae03FCc0", - "transactionIndex": 125, + "contractAddress": "0xAed6fe85bb7fA0761FfbB9D85cd2E39E5038e7c5", + "transactionIndex": 44, "gasUsed": "825217", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0x1d3bafc14ae4b76b9c2d9919d177d310ce4023d9fc63ddfec7fef4559ffeeac1", - "transactionHash": "0x34fb010ddd51e165d6adc9cd6a683eac75be8b1ace093eb2a889ec309a8753be", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000800000000000000000000000000000800000000000000000000100000000000100000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000040001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0x4a6a3f081e85c35200d77f69938fd15c3fe067e004987e042c2b92145a9acf37", + "transactionHash": "0x906132a4c53f0344b50e321b0637df5c57235590c918becbae4f2499cec0cde7", "logs": [ { - "transactionIndex": 125, - "blockNumber": 47481488, - "transactionHash": "0x34fb010ddd51e165d6adc9cd6a683eac75be8b1ace093eb2a889ec309a8753be", + "transactionIndex": 44, + "blockNumber": 47995615, + "transactionHash": "0x906132a4c53f0344b50e321b0637df5c57235590c918becbae4f2499cec0cde7", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x000000000000000000000000b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9" ], - "data": "0x000000000000000000000000000000000000000000000000002b30d6ec3a145b0000000000000000000000000000000000000000000000056782806928184b3a00000000000000000000000000000000000000000000018c26fa50c79528b70a00000000000000000000000000000000000000000000000567574f923bde36df00000000000000000000000000000000000000000000018c2725819e8162cb65", - "logIndex": 778, - "blockHash": "0x1d3bafc14ae4b76b9c2d9919d177d310ce4023d9fc63ddfec7fef4559ffeeac1" + "data": "0x00000000000000000000000000000000000000000000000000007250e6e6601e00000000000000000000000000000000000000000000000541f97c4443411c6600000000000000000000000000000000000000000000001574d264e9cdccd8ce00000000000000000000000000000000000000000000000541f909f35c5abc4800000000000000000000000000000000000000000000001574d2d73ab4b338ec", + "logIndex": 177, + "blockHash": "0x4a6a3f081e85c35200d77f69938fd15c3fe067e004987e042c2b92145a9acf37" } ], - "blockNumber": 47481488, - "cumulativeGasUsed": "26181940", + "blockNumber": 47995615, + "cumulativeGasUsed": "10097108", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b2dbdcc0b6941fae124c7dae9af5f1726bb6c522b1bb92b1dede393f5927230\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0xcf24bb7018a505bbb0f35146f9793f6ef407ce11a998817aff570a66e7848b98\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0xa4b787bb171f2fd5cba3310a8cee7eee32e4ab06f5902a6fcd62273c551115ed\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220da016c5d0170666f8c0ec63e381c612954678ab545a63ab2970cb2f3a9236b3164736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientOwnerBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"PartnerWithdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"}],\"name\":\"partnerTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens_\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"partnerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/KittyFacet.sol\":\"KittyFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"contracts/facets/KittyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\nimport {IKitty} from '../interfaces/IKitty.sol';\\n\\ncontract KittyFacet is IKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n error InsufficientOwnerBalance(uint256 available);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\\n uint256 length = tokenSet.length();\\n\\n tokens_ = new address[](length);\\n\\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\\n }\\n }\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\\n LibKitty.State storage s = LibKitty.state();\\n\\n return s.partnerBalances[partner][token];\\n }\\n\\n function partnerWithdraw(address token) external {\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 balance = s.partnerBalances[msg.sender][token];\\n\\n if (balance > 0) {\\n s.partnerBalances[msg.sender][token] = 0;\\n s.partnerBalancesTotal[token] -= balance;\\n\\n emit PartnerWithdraw(msg.sender, token, balance);\\n\\n if (token == address(0)) {\\n // NOTE: Control transfered to untrusted address\\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n // NOTE: The token is not removed from the partner's token set\\n IERC20(token).safeTransfer(msg.sender, balance);\\n }\\n }\\n }\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\\n LibDiamond.enforceIsContractOwner();\\n\\n LibKitty.State storage s = LibKitty.state();\\n\\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\\n\\n uint256 balance = token == address(0)\\n ? address(this).balance\\n : IERC20(token).balanceOf(address(this));\\n\\n uint256 available = balance - partnerBalanceTotal;\\n\\n if (amount > available) {\\n revert InsufficientOwnerBalance(available);\\n }\\n\\n if (token == address(0)) {\\n // Send ETH\\n (bool sent, ) = to.call{value: amount}('');\\n\\n if (!sent) {\\n revert Errors.EthTransferFailed();\\n }\\n } else {\\n IERC20(token).safeTransfer(to, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3abf20697535d8feceedd82cbde3105a9e6a6c6ddfc75532a588bca369ab520d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Errors} from '../libraries/Errors.sol';\\n\\ninterface IKitty {\\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\\n\\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\\n\\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\\n\\n function partnerWithdraw(address token) external;\\n\\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\\n}\\n\",\"keccak256\":\"0x6cf80a254d66f174fc82fdc474aea1b71dad36e3a6cf0e2353e2298e04041ce2\",\"license\":\"MIT\"},\"contracts/libraries/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nabstract contract Errors {\\n error AlreadyInitialized();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n error ZeroAmountOut();\\n error InsufficientOutputAmount();\\n error DeadlineExpired();\\n}\\n\",\"keccak256\":\"0x9b80854a259f0f4fe4e72968297f1d28afe40d9c62a6d59df007568be79f8b02\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50610e0f806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063044edc3c14610051578063566ed8e41461006657806378f91e371461008f578063b85eaaef146100b0575b600080fd5b61006461005f366004610b43565b6100c3565b005b610079610074366004610b85565b610306565b6040516100869190610ba2565b60405180910390f35b6100a261009d366004610bfc565b610427565b604051908152602001610086565b6100646100be366004610b85565b610480565b6100cb610661565b73ffffffffffffffffffffffffffffffffffffffff831660008181527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f460205260408120547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f092909190156101cd576040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa1580156101a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c89190610c35565b6101cf565b475b905060006101dd8383610c7d565b905080861115610221576040517f366cb4bc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166102dc5760008573ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b50509050806102d6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506102fd565b6102fd73ffffffffffffffffffffffffffffffffffffffff8816868861072c565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f2602052604081206060917f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f09190610379826107b9565b90508067ffffffffffffffff81111561039457610394610c90565b6040519080825280602002602001820160405280156103bd578160200160208202803683370190505b50935060005b8181101561041e576103d583826107c3565b8582815181106103e7576103e7610cbf565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061041681610cee565b9150506103c3565b50505050919050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f360209081526040808320938516835292905220545b92915050565b3360009081527f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f36020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020547f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f090801561065c57336000908152600383016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845282528083208390556004850190915281208054839290610546908490610c7d565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff84169033907fb15a9ee8b7bcc9bcad0d462c698be6f1a20a1d56d6d9baf2c7914ba838add7d79060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff831661063b57604051600090339083908381818185875af1925050503d80600081146105f5576040519150601f19603f3d011682016040523d82523d6000602084013e6105fa565b606091505b5050905080610635576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b61065c73ffffffffffffffffffffffffffffffffffffffff8416338361072c565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff16331461072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610218565b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261065c9084906107d6565b600061047a825490565b60006107cf83836108e5565b9392505050565b6000610838826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661090f9092919063ffffffff16565b90508051600014806108595750808060200190518101906108599190610d26565b61065c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610218565b60008260000182815481106108fc576108fc610cbf565b9060005260206000200154905092915050565b606061091e8484600085610926565b949350505050565b6060824710156109b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610218565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516109e19190610d6c565b60006040518083038185875af1925050503d8060008114610a1e576040519150601f19603f3d011682016040523d82523d6000602084013e610a23565b606091505b5091509150610a3487838387610a3f565b979650505050505050565b60608315610ad5578251600003610ace5773ffffffffffffffffffffffffffffffffffffffff85163b610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610218565b508161091e565b61091e8383815115610aea5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102189190610d88565b73ffffffffffffffffffffffffffffffffffffffff81168114610b4057600080fd5b50565b600080600060608486031215610b5857600080fd5b8335610b6381610b1e565b9250602084013591506040840135610b7a81610b1e565b809150509250925092565b600060208284031215610b9757600080fd5b81356107cf81610b1e565b6020808252825182820181905260009190848201906040850190845b81811015610bf057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610bbe565b50909695505050505050565b60008060408385031215610c0f57600080fd5b8235610c1a81610b1e565b91506020830135610c2a81610b1e565b809150509250929050565b600060208284031215610c4757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561047a5761047a610c4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d1f57610d1f610c4e565b5060010190565b600060208284031215610d3857600080fd5b815180151581146107cf57600080fd5b60005b83811015610d63578181015183820152602001610d4b565b50506000910152565b60008251610d7e818460208701610d48565b9190910192915050565b6020815260008251806020840152610da7816040850160208701610d48565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220b28948edb4918380f9c2d6d318986d7dc32530ea57a9276ae070758630eb2e3b64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/OwnershipFacet.json b/packages/hardhat/deployments/polygon/OwnershipFacet.json index 46a4ffde..0a7f414e 100644 --- a/packages/hardhat/deployments/polygon/OwnershipFacet.json +++ b/packages/hardhat/deployments/polygon/OwnershipFacet.json @@ -1,5 +1,5 @@ { - "address": "0x208f4e08017b66afcfa14be44e85ee21bb025707", + "address": "0xd1d6a41f4Ab623596D096803363AEf2f89336071", "abi": [ { "anonymous": false, @@ -47,44 +47,44 @@ "type": "function" } ], - "transactionHash": "0xb3bd1b1b5c630c3d2f8c396cd5cb8d3b6c057901bbe32697d687ad45a10e2d5a", + "transactionHash": "0xaa6bd67763be3cba85b39a5e4c75c7086341afe49380300cf34f847129c224f0", "receipt": { "to": null, - "from": "0x67e21394bbc46c010d9b8dcf00172ab7996964be", - "contractAddress": "0x208f4e08017b66afcfa14be44e85ee21bb025707", - "transactionIndex": "0x66", - "gasUsed": "0x33152", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0x32ca831af5721fde0789af596d99a1413c02c600f52c3680ce9c1ef915adac8d", - "transactionHash": "0xb3bd1b1b5c630c3d2f8c396cd5cb8d3b6c057901bbe32697d687ad45a10e2d5a", + "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", + "contractAddress": "0xd1d6a41f4Ab623596D096803363AEf2f89336071", + "transactionIndex": 195, + "gasUsed": "209234", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0xe6a953649017915411d273a9df05e9a1b93a192eb01f2b7eb874aaebfb4e478f", + "transactionHash": "0xaa6bd67763be3cba85b39a5e4c75c7086341afe49380300cf34f847129c224f0", "logs": [ { + "transactionIndex": 195, + "blockNumber": 47995200, + "transactionHash": "0xaa6bd67763be3cba85b39a5e4c75c7086341afe49380300cf34f847129c224f0", "address": "0x0000000000000000000000000000000000001010", - "blockHash": "0x32ca831af5721fde0789af596d99a1413c02c600f52c3680ce9c1ef915adac8d", - "blockNumber": "0x2d47930", - "data": "0x00000000000000000000000000000000000000000000000000078131a8509b8c00000000000000000000000000000000000000000000000567e164f40ff056120000000000000000000000000000000000000000000001836e2aaef98d01b07000000000000000000000000000000000000000000000000567d9e3c2679fba860000000000000000000000000000000000000000000001836e32302b35524bfc", - "logIndex": "0x223", - "removed": false, "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" ], - "transactionHash": "0xb3bd1b1b5c630c3d2f8c396cd5cb8d3b6c057901bbe32697d687ad45a10e2d5a", - "transactionIndex": "0x66" + "data": "0x000000000000000000000000000000000000000000000000000800c4a8d88b10000000000000000000000000000000000000000000000005421f1c24063d3604000000000000000000000000000000000000000000025c7d88a6a3e47fc34fa700000000000000000000000000000000000000000000000542171b5f5d64aaf4000000000000000000000000000000000000000000025c7d88aea4a9289bdab7", + "logIndex": 673, + "blockHash": "0xe6a953649017915411d273a9df05e9a1b93a192eb01f2b7eb874aaebfb4e478f" } ], - "blockNumber": "0x2d47930", - "cumulativeGasUsed": "0x1130f78", - "status": "0x1" + "blockNumber": 47995200, + "cumulativeGasUsed": "27852713", + "status": 1, + "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0543f1b9a307b6e645ab4a866306bf25", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0x2836ab3ca2aebaaffbafed73912c31012d34b0a20860394fd7050199401de018\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea26469706673582212204c5bd73f3242847643501a2b24c9f180c115243c6af9f4c507b1c78cb0ea05f864736f6c63430008130033", + "numDeployments": 2, + "solcInputHash": "4bd33b0efaadcd28492d25c3625ab942", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"OwnershipTransferred(address,address)\":{\"details\":\"This emits when ownership of a contract changes.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"returns\":{\"owner_\":\"The address of the owner.\"}},\"transferOwnership(address)\":{\"details\":\"Set _newOwner to address(0) to renounce any ownership.\",\"params\":{\"_newOwner\":\"The address of the new owner of the contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"owner()\":{\"notice\":\"Get the address of the owner\"},\"transferOwnership(address)\":{\"notice\":\"Set the address of the new owner of the contract\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/OwnershipFacet.sol\":\"OwnershipFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"contracts/facets/OwnershipFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\\nimport {IERC173} from '../interfaces/IERC173.sol';\\n\\ncontract OwnershipFacet is IERC173 {\\n function transferOwnership(address _newOwner) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.setContractOwner(_newOwner);\\n }\\n\\n function owner() external view override returns (address owner_) {\\n owner_ = LibDiamond.contractOwner();\\n }\\n}\\n\",\"keccak256\":\"0xd14213dfd60c9476041ad22fcb96d4d81cda561979c24befa9de88220dae51d2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC173.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title ERC-173 Contract Ownership Standard\\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\\n/* is ERC165 */\\ninterface IERC173 {\\n /// @dev This emits when ownership of a contract changes.\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /// @notice Get the address of the owner\\n /// @return owner_ The address of the owner.\\n function owner() external view returns (address owner_);\\n\\n /// @notice Set the address of the new owner of the contract\\n /// @dev Set _newOwner to address(0) to renounce any ownership.\\n /// @param _newOwner The address of the new owner of the contract\\n function transferOwnership(address _newOwner) external;\\n}\\n\",\"keccak256\":\"0x9d9a87c70387f7cbbb4b9436688c03f11faa194f4a0205af4f7230cbb98be67a\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506102d6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638da5cb5b1461003b578063f2fde38b1461006c575b600080fd5b610043610081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61007f61007a366004610263565b6100c6565b005b60006100c17fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b6100ce6100da565b6100d7816101a9565b50565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c6003015473ffffffffffffffffffffffffffffffffffffffff1633146101a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201527f6572000000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff8481169182179093556040517fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60006020828403121561027557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461029957600080fd5b939250505056fea2646970667358221220e4d4a2418a94c1dcee8ce6184e1e93d16b760fb6e8cb1bacd1650e8bcd18ef1a64736f6c63430008130033", "devdoc": { "events": { "OwnershipTransferred(address,address)": { diff --git a/packages/hardhat/deployments/polygon/UniV2LikeFacet.json b/packages/hardhat/deployments/polygon/UniV2LikeFacet.json index 30bc6dea..bba07574 100644 --- a/packages/hardhat/deployments/polygon/UniV2LikeFacet.json +++ b/packages/hardhat/deployments/polygon/UniV2LikeFacet.json @@ -1,5 +1,5 @@ { - "address": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", + "address": "0xb88582B085a7ce62Ad41FAd01737140e8Ea95f78", "abi": [ { "inputs": [], @@ -219,44 +219,44 @@ "type": "function" } ], - "transactionHash": "0xebc4894013ee3a1fdd20fe204db12cf2f2aa85a851d0fae95fd553e53cdbdfdc", + "transactionHash": "0xc928d4f094b47af5abe1e9c1c26b1ce58e8f0e349df1f45066cee9e7a0191fed", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0xd9760e73940638706d764024499EB1Fa0612Bb8E", - "transactionIndex": 168, - "gasUsed": "2056445", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0x7ecd5e6e19fa0afe1c94d2157003cd1b20543b8f84f1ec00e44409c53fb8ded6", - "transactionHash": "0xebc4894013ee3a1fdd20fe204db12cf2f2aa85a851d0fae95fd553e53cdbdfdc", + "contractAddress": "0xb88582B085a7ce62Ad41FAd01737140e8Ea95f78", + "transactionIndex": 55, + "gasUsed": "2056433", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000120000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0x1622d546d1c18b6a75c281b206aca6a8df6d64e7658f73b28e82a4936a0e6e7c", + "transactionHash": "0xc928d4f094b47af5abe1e9c1c26b1ce58e8f0e349df1f45066cee9e7a0191fed", "logs": [ { - "transactionIndex": 168, - "blockNumber": 47792800, - "transactionHash": "0xebc4894013ee3a1fdd20fe204db12cf2f2aa85a851d0fae95fd553e53cdbdfdc", + "transactionIndex": 55, + "blockNumber": 47995754, + "transactionHash": "0xc928d4f094b47af5abe1e9c1c26b1ce58e8f0e349df1f45066cee9e7a0191fed", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" ], - "data": "0x0000000000000000000000000000000000000000000000000090655f759ae2e40000000000000000000000000000000000000000000000054e629e2955cc55bf0000000000000000000000000000000000000000000002353cc67c79eae4a8ab0000000000000000000000000000000000000000000000054dd238c9e03172db0000000000000000000000000000000000000000000002353d56e1d9607f8b8f", - "logIndex": 884, - "blockHash": "0x7ecd5e6e19fa0afe1c94d2157003cd1b20543b8f84f1ec00e44409c53fb8ded6" + "data": "0x00000000000000000000000000000000000000000000000000089d2d9023bb1d0000000000000000000000000000000000000000000000054152c8c863911e0f0000000000000000000000000000000000000000000013e3de445bb12b6d99dc000000000000000000000000000000000000000000000005414a2b9ad36d62f20000000000000000000000000000000000000000000013e3de4cf8debb9154f9", + "logIndex": 225, + "blockHash": "0x1622d546d1c18b6a75c281b206aca6a8df6d64e7658f73b28e82a4936a0e6e7c" } ], - "blockNumber": 47792800, - "cumulativeGasUsed": "26632377", + "blockNumber": 47995754, + "cumulativeGasUsed": "11457496", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56e7341e6a317f670cc3df2ee1e18b3a47c8e11f302db67b787aba91007d2280\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xcf11728bd04fa6c509bfa1093d6e6f9490a1b2fb41a94144d13d0c0abe3db24a\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122028377ffadb796bef56e7d2726feb04400946bd17d1c1d2248fb8b1265e86d99e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint16[]\",\"name\":\"poolFeesBps\",\"type\":\"uint16[]\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV2Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"poolFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"}],\"internalType\":\"struct IUniV2Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V2 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses. Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`. Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV2LikeFacet.sol\":\"UniV2LikeFacet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV2LikeFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V2 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n *\\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\\n *\\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\\n */\\ncontract UniV2LikeFacet is IUniV2Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (isFromEth) {\\n params.tokenIn = address(s.weth);\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(s.weth);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (params.tokenIn > params.tokenOut) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 25 bps, multiply by 9975\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n amountOut =\\n ((params.amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the pool\\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the pool\\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\\n }\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\\n\\n IUniswapV2Pair(params.pool).swap(\\n zeroForOne ? 0 : amountOut,\\n zeroForOne ? amountOut : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n LibWarp.State storage s = LibWarp.state();\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n\\n uint256 tokenOutBalancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n params.amountIn,\\n params.tokens,\\n params.pools\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (isFromEth) {\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n s.weth.deposit{value: msg.value}();\\n\\n // Transfer tokens to the first pool\\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\\n } else {\\n // Permit tokens / set allowance\\n s.permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n\\n // Transfer tokens from msg.sender to the first pool\\n s.permit2.transferFrom(\\n msg.sender,\\n params.pools[0],\\n (uint160)(params.amountIn),\\n params.tokens[0]\\n );\\n }\\n\\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = isToEth\\n ? address(this).balance\\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amounts[poolLength]\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n s.weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xea45669f18797f167c70a3fc6ee194fa38fea7a14d310045083d2b64bb88397d\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV2Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n uint16[] poolFeesBps;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n address pool;\\n uint16 feeBps;\\n uint16 slippageBps;\\n address partner;\\n address tokenIn;\\n address tokenOut;\\n uint16 poolFeeBps;\\n uint48 deadline;\\n }\\n\\n function uniswapV2LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV2LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x8dec0c768b0e3875e1e59d241435bcdf88de646aa674ad20c26204d166d6acc9\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50612471806100206000396000f3fe6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c806383cf9ad51461002e578063a39a934214610053575b600080fd5b61004161003c366004611d63565b610066565b60405190815260200160405180910390f35b610041610061366004611f65565b61093e565b600082610140015165ffffffffffff164211156100af576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516101008401517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109173ffffffffffffffffffffffffffffffffffffffff90811615911615600081610199576101008701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610170573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019491906120a5565b61019b565b475b905082156101c157835473ffffffffffffffffffffffffffffffffffffffff1660e08801525b81156101e657835473ffffffffffffffffffffffffffffffffffffffff166101008801525b600080886060015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025c91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915088610100015173ffffffffffffffffffffffffffffffffffffffff168960e0015173ffffffffffffffffffffffffffffffffffffffff1611156102c057905b610120890151895161ffff61271092830316918402908202908101908302816102eb576102eb61212c565b0497505061030189602001518a60a001516113e2565b87101561033a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8415610430578851341461037a576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b1580156103e657600080fd5b505af11580156103fa573d6000803e3d6000fd5b50505060608b01518b5160e08d015161042b945073ffffffffffffffffffffffffffffffffffffffff169250611412565b6105b5565b60018601546040805160e080820183528c015173ffffffffffffffffffffffffffffffffffffffff908116606083019081528d51821660808401526101408e01805165ffffffffffff90811660a08601528e35811660c08601529184523060208086019190915290519091169383019390935290921691632b67b570913391906104bc908d018d61215b565b6040518563ffffffff1660e01b81526004016104db94939291906121c7565b600060405180830381600087803b1580156104f557600080fd5b505af1158015610509573d6000803e3d6000fd5b50505050600186015460608a01518a5160e08c01516040517f36c7851600000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff93841660248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b600089610100015173ffffffffffffffffffffffffffffffffffffffff168a60e0015173ffffffffffffffffffffffffffffffffffffffff16106105fa5760006105fd565b60015b9050896060015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8261062a578961062d565b60005b8361063957600061063b565b8a5b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505060008561075e576101008b01516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075991906120a5565b610760565b475b905084811080610778575061077589866122b8565b81105b156107af576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107cd8b60c001518c61010001518d608001518e602001518d6114a4565b985085156108fc5787546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018b905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561084057600080fd5b505af1158015610854573d6000803e3d6000fd5b5050505060008b6040015173ffffffffffffffffffffffffffffffffffffffff168a60405160006040518083038185875af1925050503d80600081146108b6576040519150601f19603f3d011682016040523d82523d6000602084013e6108bb565b606091505b50509050806108f6576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610930565b6109308b604001518a8d610100015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b505050505050505092915050565b60008260c0015165ffffffffffff16421115610986576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101208301515161010084015180517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10929160009182919082906109cc576109cc6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168761010001518481518110610a1d57610a1d6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600081610afb578761010001518481518110610a5c57610a5c6122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af691906120a5565b610afd565b475b90506000610b1f89604001518a600001518b61010001518c6101200151611565565b9050610b3389602001518a608001516113e2565b8160018351610b4291906122fa565b81518110610b5257610b526122cb565b60200260200101511015610b92576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8315610cc95788513414610bd2576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8554604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163d0e30db0913491600480830192600092919082900301818588803b158015610c3e57600080fd5b505af1158015610c52573d6000803e3d6000fd5b5050505050610cc4896101200151600081518110610c7257610c726122cb565b60200260200101518a600001518b6101000151600081518110610c9757610c976122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166114129092919063ffffffff16565b610f1e565b8560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808f6101000151600081518110610d3857610d386122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018f6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018f60c0015165ffffffffffff1681526020018e6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018d60c0015165ffffffffffff168152508b8060200190610dde919061215b565b6040518563ffffffff1660e01b8152600401610dfd94939291906121c7565b600060405180830381600087803b158015610e1757600080fd5b505af1158015610e2b573d6000803e3d6000fd5b5050505060018601546101208a0151805173ffffffffffffffffffffffffffffffffffffffff909216916336c78516913391600090610e6c57610e6c6122cb565b60200260200101518c600001518d6101000151600081518110610e9157610e916122cb565b60200260200101516040518563ffffffff1660e01b8152600401610eeb949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050505b60005b85811015611127576000610f368260016122b8565b905060008b61010001518281518110610f5157610f516122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168c61010001518481518110610f8657610f866122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610610fb0576000610fb3565b60015b9050600060028d610100015151610fca91906122fa565b8410610fd65730610ff6565b8c61012001518381518110610fed57610fed6122cb565b60200260200101515b90508c6101200151848151811061100f5761100f6122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f8361105657868581518110611049576110496122cb565b6020026020010151611059565b60005b84611065576000611080565b878681518110611077576110776122cb565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b15801561110057600080fd5b505af1158015611114573d6000803e3d6000fd5b505060019095019450610f219350505050565b506000836111e5578961010001518681518110611146576111466122cb565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e091906120a5565b6111e7565b475b9050828110806111ff57506111fc88846122b8565b81105b15611236576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112868a60e001518b61010001518881518110611255576112556122cb565b60200260200101518c60a001518d60200151868b81518110611279576112796122cb565b60200260200101516114a4565b975083156113b55786546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018a905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b5050505060008a6060015173ffffffffffffffffffffffffffffffffffffffff168960405160006040518083038185875af1925050503d806000811461136f576040519150601f19603f3d011682016040523d82523d6000602084013e611374565b606091505b50509050806113af576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506113d5565b6113d58a60600151898c61010001518981518110610c9757610c976122cb565b5050505050505092915050565b60006127106113f1838261230d565b6113ff9061ffff168561232f565b6114099190612346565b90505b92915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261149f90849061179a565b505050565b60006107d061ffff851611156114ef576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115611501575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff89161561153b576064603284020461153e565b60005b9050808303838214611556576115568a8a84846118a9565b50505090910395945050505050565b805182516060919067ffffffffffffffff81111561158557611585611c2e565b6040519080825280602002602001820160405280156115ae578160200160208202803683370190505b50915084826000815181106115c5576115c56122cb565b60200260200101818152505060005b818110156117905760008582815181106115f0576115f06122cb565b6020026020010151905060008683600161160a91906122b8565b8151811061161a5761161a6122cb565b602002602001015190506000898481518110611638576116386122cb565b602002602001015161271061164d919061230d565b61ffff169050600080888681518110611668576116686122cb565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906120dc565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111561173957905b828b0282612710020181848d0202816117545761175461212c565b049a508a886117648860016122b8565b81518110611774576117746122cb565b60209081029190910101525050600190930192506115d4915050565b5050949350505050565b60006117fc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119ae9092919063ffffffff16565b905080516000148061181d57508080602001905181019061181d9190612381565b61149f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016114e6565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156119195773ffffffffffffffffffffffffffffffffffffffff85166000908152600282016020526040902061191790856119c5565b505b61192381866119c5565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60606119bd84846000856119e7565b949350505050565b60006114098373ffffffffffffffffffffffffffffffffffffffff8416611b00565b606082471015611a79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016114e6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611aa291906123ce565b60006040518083038185875af1925050503d8060008114611adf576040519150601f19603f3d011682016040523d82523d6000602084013e611ae4565b606091505b5091509150611af587838387611b4f565b979650505050505050565b6000818152600183016020526040812054611b475750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561140c565b50600061140c565b60608315611be5578251600003611bde5773ffffffffffffffffffffffffffffffffffffffff85163b611bde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114e6565b50816119bd565b6119bd8383815115611bfa5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e691906123ea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611c8157611c81611c2e565b60405290565b604051610140810167ffffffffffffffff81118282101715611c8157611c81611c2e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611cf257611cf2611c2e565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d1e57600080fd5b919050565b803561ffff81168114611d1e57600080fd5b803565ffffffffffff81168114611d1e57600080fd5b600060408284031215611d5d57600080fd5b50919050565b600080828403610180811215611d7857600080fd5b61016080821215611d8857600080fd5b611d90611c5d565b91508435825260208501356020830152611dac60408601611cfa565b6040830152611dbd60608601611cfa565b6060830152611dce60808601611d23565b6080830152611ddf60a08601611d23565b60a0830152611df060c08601611cfa565b60c0830152611e0160e08601611cfa565b60e0830152610100611e14818701611cfa565b90830152610120611e26868201611d23565b90830152610140611e38868201611d35565b9083015290925083013567ffffffffffffffff811115611e5757600080fd5b611e6385828601611d4b565b9150509250929050565b600067ffffffffffffffff821115611e8757611e87611c2e565b5060051b60200190565b600082601f830112611ea257600080fd5b81356020611eb7611eb283611e6d565b611cab565b82815260059290921b84018101918181019086841115611ed657600080fd5b8286015b84811015611ef857611eeb81611d23565b8352918301918301611eda565b509695505050505050565b600082601f830112611f1457600080fd5b81356020611f24611eb283611e6d565b82815260059290921b84018101918181019086841115611f4357600080fd5b8286015b84811015611ef857611f5881611cfa565b8352918301918301611f47565b60008060408385031215611f7857600080fd5b823567ffffffffffffffff80821115611f9057600080fd5b908401906101408287031215611fa557600080fd5b611fad611c87565b8235815260208301356020820152604083013582811115611fcd57600080fd5b611fd988828601611e91565b604083015250611feb60608401611cfa565b6060820152611ffc60808401611d23565b608082015261200d60a08401611d23565b60a082015261201e60c08401611d35565b60c082015261202f60e08401611cfa565b60e0820152610100808401358381111561204857600080fd5b61205489828701611f03565b828401525050610120808401358381111561206e57600080fd5b61207a89828701611f03565b82840152505080945050602085013591508082111561209857600080fd5b50611e6385828601611d4b565b6000602082840312156120b757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff81168114611d1e57600080fd5b6000806000606084860312156120f157600080fd5b6120fa846120be565b9250612108602085016120be565b9150604084015163ffffffff8116811461212157600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261219057600080fd5b83018035915067ffffffffffffffff8211156121ab57600080fd5b6020019150368190038213156121c057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561140c5761140c612289565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561140c5761140c612289565b61ffff82811682821603908082111561232857612328612289565b5092915050565b808202811582820484141761140c5761140c612289565b60008261237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561239357600080fd5b815180151581146123a357600080fd5b9392505050565b60005b838110156123c55781810151838201526020016123ad565b50506000910152565b600082516123e08184602087016123aa565b9190910192915050565b60208152600082518060208401526124098160408501602087016123aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220e08b8f80b4dddb7f8af03bd2fd427f853eee605800c1cc2ba197e7dd55f22eec64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/UniV3Callback.json b/packages/hardhat/deployments/polygon/UniV3Callback.json index 29ce5c3c..5e8ee980 100644 --- a/packages/hardhat/deployments/polygon/UniV3Callback.json +++ b/packages/hardhat/deployments/polygon/UniV3Callback.json @@ -1,5 +1,5 @@ { - "address": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", + "address": "0x3a3483806587f0e47c000A9956b147e9751923bE", "abi": [ { "inputs": [], @@ -53,44 +53,44 @@ "type": "function" } ], - "transactionHash": "0x4d5956e7033cd124df0c1b17322167942c4211e88f07038692b81a00fd092c02", + "transactionHash": "0x3a3f29a0626a2634a2c5c110ce30eb8ccfedf090c64182a0cfb642b388283ebf", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x055385b7dC1c74a32EeF0A53f303486feE26a997", - "transactionIndex": 61, + "contractAddress": "0x3a3483806587f0e47c000A9956b147e9751923bE", + "transactionIndex": 21, "gasUsed": "480236", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0xb5ee1aa56d66dcf96fe14e41acb2e1b1b3ce4ae10acd15960945bb2bc51b6266", - "transactionHash": "0x4d5956e7033cd124df0c1b17322167942c4211e88f07038692b81a00fd092c02", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000001000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100020000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000020100000", + "blockHash": "0x46f405ce0d5f86074dc3978c0292b4cf10d3c4a5ea2f3b6a118a16a579913e7d", + "transactionHash": "0x3a3f29a0626a2634a2c5c110ce30eb8ccfedf090c64182a0cfb642b388283ebf", "logs": [ { - "transactionIndex": 61, - "blockNumber": 47792805, - "transactionHash": "0x4d5956e7033cd124df0c1b17322167942c4211e88f07038692b81a00fd092c02", + "transactionIndex": 21, + "blockNumber": 47995778, + "transactionHash": "0x3a3f29a0626a2634a2c5c110ce30eb8ccfedf090c64182a0cfb642b388283ebf", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x000000000000000000000000794e44d1334a56fea7f4df12633b88820d0c5888" ], - "data": "0x0000000000000000000000000000000000000000000000000019d9082076d3e00000000000000000000000000000000000000000000000054c45ba13a95064d30000000000000000000000000000000000000000000002357d83b03a2b1d39fb0000000000000000000000000000000000000000000000054c2be10b88d990f30000000000000000000000000000000000000000000002357d9d89424b940ddb", - "logIndex": 242, - "blockHash": "0xb5ee1aa56d66dcf96fe14e41acb2e1b1b3ce4ae10acd15960945bb2bc51b6266" + "data": "0x0000000000000000000000000000000000000000000000000097c8b253ec0e840000000000000000000000000000000000000000000000053fa96daf3e97d92b00000000000000000000000000000000000000000000022f82361a95f557e20b0000000000000000000000000000000000000000000000053f11a4fceaabcaa700000000000000000000000000000000000000000000022f82cde3484943f08f", + "logIndex": 85, + "blockHash": "0x46f405ce0d5f86074dc3978c0292b4cf10d3c4a5ea2f3b6a118a16a579913e7d" } ], - "blockNumber": 47792805, - "cumulativeGasUsed": "29491181", + "blockNumber": 47995778, + "cumulativeGasUsed": "3418722", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220f845957e970da0e138f47769a26587108a1bc97c64e053caca1d319fae53ae4764736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"algebraSwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"uniswapV3SwapCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"algebraSwapCallback(int256,int256,bytes)\":{\"notice\":\"NOTE: None of these arguments can be trusted\"},\"uniswapV3SwapCallback(int256,int256,bytes)\":{\"notice\":\"See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol NOTE: None of these arguments can be trusted\"}},\"notice\":\"NOTE: Using a shared internal functions uses about 3K more gas than having two externals with the code duplicated\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Callback.sol\":\"UniV3Callback\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506107c6806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632c8958f61461003b578063fa461e331461003b575b600080fd5b61004e610049366004610656565b610050565b005b61005861005e565b50505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001146100bc576040517f7c0a084d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5481527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c5473ffffffffffffffffffffffffffffffffffffffff908116602083018190527f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d54909116928201929092529030900361018f578051604082015161018a9173ffffffffffffffffffffffffffffffffffffffff9091169033906102a1565b610257565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020820151825160408085015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523360248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561023e57600080fd5b505af1158015610252573d6000803e3d6000fd5b505050505b507f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261032e908490610333565b505050565b6000610395826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104479092919063ffffffff16565b90508051600014806103b65750808060200190518101906103b691906106d6565b61032e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6060610456848460008561045e565b949350505050565b6060824710156104f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161043e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516105199190610723565b60006040518083038185875af1925050503d8060008114610556576040519150601f19603f3d011682016040523d82523d6000602084013e61055b565b606091505b509150915061056c87838387610577565b979650505050505050565b6060831561060d5782516000036106065773ffffffffffffffffffffffffffffffffffffffff85163b610606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161043e565b5081610456565b61045683838151156106225781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e919061073f565b6000806000806060858703121561066c57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561069257600080fd5b818701915087601f8301126106a657600080fd5b8135818111156106b557600080fd5b8860208285010111156106c757600080fd5b95989497505060200194505050565b6000602082840312156106e857600080fd5b815180151581146106f857600080fd5b9392505050565b60005b8381101561071a578181015183820152602001610702565b50506000910152565b600082516107358184602087016106ff565b9190910192915050565b602081526000825180602084015261075e8160408501602087016106ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212201f941fe285479a6e93903d5f609ce7076eeca69f1435e02124d22796a0f2b38164736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/UniV3Like.json b/packages/hardhat/deployments/polygon/UniV3Like.json index 892e04de..25b7db88 100644 --- a/packages/hardhat/deployments/polygon/UniV3Like.json +++ b/packages/hardhat/deployments/polygon/UniV3Like.json @@ -1,5 +1,5 @@ { - "address": "0x8A895ecbE10Aa09441aA19D2c0DB00F5DCF72481", + "address": "0x7f811E8615331f7F89e1781273Eea54d46C3B869", "abi": [ { "inputs": [], @@ -219,44 +219,44 @@ "type": "function" } ], - "transactionHash": "0x0b68f8e94d12f7b2bbb45eae402465c42445f9dd16bacfdd311554ba3108f850", + "transactionHash": "0x83b4ea2ae27c709edb0091acedc111bfdc15652fb7c5598dcc37933d6582e102", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x8A895ecbE10Aa09441aA19D2c0DB00F5DCF72481", - "transactionIndex": 104, + "contractAddress": "0x7f811E8615331f7F89e1781273Eea54d46C3B869", + "transactionIndex": 98, "gasUsed": "1989150", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0xe5a1eff62a4d60238ca5e88721071df9778dc80c846503dd60371e1da37e078c", - "transactionHash": "0x0b68f8e94d12f7b2bbb45eae402465c42445f9dd16bacfdd311554ba3108f850", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0xbb7da9cbd0b981b6914f7afa63348adf6bc61540906aca356435a443ec78b3c7", + "transactionHash": "0x83b4ea2ae27c709edb0091acedc111bfdc15652fb7c5598dcc37933d6582e102", "logs": [ { - "transactionIndex": 104, - "blockNumber": 47792809, - "transactionHash": "0x0b68f8e94d12f7b2bbb45eae402465c42445f9dd16bacfdd311554ba3108f850", + "transactionIndex": 98, + "blockNumber": 47996001, + "transactionHash": "0x83b4ea2ae27c709edb0091acedc111bfdc15652fb7c5598dcc37933d6582e102", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" ], - "data": "0x000000000000000000000000000000000000000000000000006c6b06d76055580000000000000000000000000000000000000000000000054bcbd7322f0ed3970000000000000000000000000000000000000000000002359d98c6dda3224de10000000000000000000000000000000000000000000000054b5f6c2b57ae7e3f0000000000000000000000000000000000000000000002359e0531e47a82a339", - "logIndex": 317, - "blockHash": "0xe5a1eff62a4d60238ca5e88721071df9778dc80c846503dd60371e1da37e078c" + "data": "0x0000000000000000000000000000000000000000000000000034c4a7402d60be0000000000000000000000000000000000000000000000053eea136ea526888b000000000000000000000000000000000000000000025c7e53c85d7a25c32d020000000000000000000000000000000000000000000000053eb54ec764f927cd000000000000000000000000000000000000000000025c7e53fd222165f08dc0", + "logIndex": 435, + "blockHash": "0xbb7da9cbd0b981b6914f7afa63348adf6bc61540906aca356435a443ec78b3c7" } ], - "blockNumber": 47792809, - "cumulativeGasUsed": "13832647", + "blockNumber": 47996001, + "cumulativeGasUsed": "21854620", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0x5659b5ba56e4404ad6a64174b0d3b5ce00902f13a4726a6804250cecfccc1508\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89bc1011edc38e6b0575be8b7f43aa2530bff8eaeff5da0ad1f479da30b0a84\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0x3d5f724620e8dffd077b86613050bca34d60dab1288090558a63db18c8a8b9b1\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220de90966e8f3f7385ea0dc1066bebca7e7759685da0f701e6f84217538e98c90764736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "025166ddb0f771753ceec554ac05c5f7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficienTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"internalType\":\"struct IUniV3Like.ExactInputParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"struct IUniV3Like.ExactInputSingleParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"uniswapV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"notice\":\"A router for any Uniswap V3 fork The pools are not trusted to deliver the correct amount of tokens, so the router verifies this. The pool addresses passed in as a parameter instead of being looked up from the factory. The caller may use `getPair` on the factory to calculate pool addresses.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/UniV3Like.sol\":\"UniV3Like\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/UniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\n/**\\n * NOTE: Using a shared internal functions uses about 3K more gas than\\n * having two externals with the code duplicated\\n */\\ncontract UniV3Callback is IUniV3Callback {\\n using SafeERC20 for IERC20;\\n\\n function swapCallback() private {\\n if (LibUniV3Like.state().isActive != 1) {\\n revert CallbackInactive();\\n }\\n\\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\\n\\n if (callback.payer == address(this)) {\\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\\n } else {\\n LibWarp.state().permit2.transferFrom(\\n callback.payer,\\n msg.sender,\\n (uint160)(callback.amount),\\n callback.token\\n );\\n }\\n\\n LibUniV3Like.state().isActive = 0;\\n }\\n\\n /**\\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\\n *\\n * NOTE: None of these arguments can be trusted\\n */\\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n\\n /**\\n * NOTE: None of these arguments can be trusted\\n */\\n function algebraSwapCallback(int256, int256, bytes calldata) external {\\n swapCallback();\\n }\\n}\\n\",\"keccak256\":\"0xa759bd8843aa88e32cd5e15e3278c94a2a34f4d2a0dcadea453899108e0a59d6\",\"license\":\"MIT\"},\"contracts/facets/UniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {IUniV3Callback} from './UniV3Callback.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\n/**\\n * A router for any Uniswap V3 fork\\n *\\n * The pools are not trusted to deliver the correct amount of tokens, so the router\\n * verifies this.\\n *\\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\\n * may use `getPair` on the factory to calculate pool addresses.\\n */\\ncontract UniV3Like is IUniV3Like {\\n using SafeERC20 for IERC20;\\n using Address for address;\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n bool isFromEth = params.tokenIn == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokenIn = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokenOut = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = params.tokenIn < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({\\n payer: isFromEth ? address(this) : msg.sender,\\n token: params.tokenIn,\\n amount: params.amountIn\\n })\\n );\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n params.deadline\\n ),\\n permit.signature\\n );\\n }\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(params.amountIn),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // TODO: This is read twice. Compare gas usage\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut) {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n uint256 poolLength = params.pools.length;\\n bool isFromEth = params.tokens[0] == address(0);\\n bool isToEth = params.tokens[poolLength] == address(0);\\n address payer = isFromEth ? address(this) : msg.sender;\\n\\n if (isFromEth) {\\n IWETH weth = LibWarp.state().weth;\\n\\n params.tokens[0] = address(weth);\\n\\n // From ETH\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n weth.deposit{value: msg.value}();\\n }\\n\\n if (isToEth) {\\n params.tokens[poolLength] = address(LibWarp.state().weth);\\n }\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n amountOut = params.amountIn;\\n\\n if (!isFromEth) {\\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle(\\n IAllowanceTransfer.PermitDetails({\\n token: params.tokens[0],\\n amount: (uint160)(params.amountIn),\\n expiration: params.deadline,\\n nonce: (uint48)(permit.nonce)\\n }),\\n address(this),\\n (uint256)(params.deadline)\\n ),\\n permit.signature\\n );\\n }\\n\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne;\\n\\n unchecked {\\n indexPlusOne = index + 1;\\n }\\n\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\\n address(this),\\n zeroForOne,\\n int256(amountOut),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n amountOut = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n // TODO: Compare check-and-set with set\\n payer = address(this);\\n\\n index = indexPlusOne;\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n if (\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\\n ) {\\n revert InsufficienTokensDelivered();\\n }\\n\\n // NOTE: Fee is collected as WETH instead of ETH\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokens[poolLength],\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n if (isToEth) {\\n // Unwrap WETH\\n LibWarp.state().weth.withdraw(amountOut);\\n\\n (bool sent, ) = params.recipient.call{value: amountOut}('');\\n\\n if (!sent) {\\n revert EthTransferFailed();\\n }\\n } else {\\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x24d951973c414bf7384ab3c8862934f4ea125ba750c0f15f804325faa79a6a6c\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IUniV3Like {\\n error InsufficienTokensDelivered();\\n error DeadlineExpired();\\n error InsufficientOutputAmount();\\n error EthTransferFailed();\\n error IncorrectEthValue();\\n\\n struct ExactInputParams {\\n uint256 amountIn;\\n uint256 amountOut;\\n address recipient;\\n uint16 slippageBps;\\n uint16 feeBps;\\n uint48 deadline;\\n address partner;\\n address[] tokens;\\n address[] pools;\\n }\\n\\n struct ExactInputSingleParams {\\n address recipient;\\n address partner;\\n uint16 feeBps;\\n uint16 slippageBps;\\n uint256 amountIn;\\n uint48 deadline;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountOut;\\n address pool;\\n }\\n\\n function uniswapV3LikeExactInputSingle(\\n ExactInputSingleParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n\\n function uniswapV3LikeExactInput(\\n ExactInputParams memory params,\\n PermitParams calldata permit\\n ) external payable returns (uint256 amountOut);\\n}\\n\",\"keccak256\":\"0xec1f28bdd5499b3065bebb77fa28e1a5b03dd07d22cb0273987f8f3dc9796096\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061233a806100206000396000f3fe6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100295760003560e01c80630bdf6a0d1461002e5780632494644d14610053575b600080fd5b61004161003c366004611cfb565b610066565b60405190815260200160405180910390f35b610041610061366004611ea8565b610941565b60008260a0015165ffffffffffff164211156100ae576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015160e084015173ffffffffffffffffffffffffffffffffffffffff9182161591161581156101b9577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660c0860181905260808601513414610156576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561019e57600080fd5b505af11580156101b2573d6000803e3d6000fd5b5050505050505b80156101fd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105473ffffffffffffffffffffffffffffffffffffffff1660e08601525b60e08501516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102929190611fc2565b905060008660e0015173ffffffffffffffffffffffffffffffffffffffff168760c0015173ffffffffffffffffffffffffffffffffffffffff16109050610332604051806060016040528089608001518152602001866102f257336102f4565b305b73ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b836104a3577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808d60c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018d6080015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60a0015165ffffffffffff1681526020018c6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018b60a0015165ffffffffffff168152508980602001906104519190611fdb565b6040518563ffffffff1660e01b81526004016104709493929190612047565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050505b80156105835761012087015160808801516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af115801561054a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061056e9190612109565b9150508061057b9061215c565b955050610667565b61012087015160808801516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015610633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106579190612109565b5090506106638161215c565b9550505b61066f61159e565b61068287610100015188606001516115fe565b8510156106bb576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08701516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190611fc2565b90508281108061076857506107658684612194565b81105b1561079f576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107bd88602001518960e001518a604001518b61010001518a61162e565b9550831561090c577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561085057600080fd5b505af1158015610864573d6000803e3d6000fd5b505050506000886000015173ffffffffffffffffffffffffffffffffffffffff168760405160006040518083038185875af1925050503d80600081146108c6576040519150601f19603f3d011682016040523d82523d6000602084013e6108cb565b606091505b5050905080610906576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50610936565b875160e08901516109369173ffffffffffffffffffffffffffffffffffffffff90911690886116ef565b505050505092915050565b60008260a0015165ffffffffffff16421115610989576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101008301515160e08401518051600091829182906109aa576109aa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614905060008073ffffffffffffffffffffffffffffffffffffffff168660e0015184815181106109fa576109fa6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16149050600082610a285733610a2a565b305b90508215610b48577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff90921691829190600090610a8657610a866121a7565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015287513414610ae5576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b5050505050505b8115610bdb577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e105460e0880151805173ffffffffffffffffffffffffffffffffffffffff9092169186908110610ba057610ba06121a7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b60008760e001518581518110610bf357610bf36121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d9190611fc2565b88519650905083610e1e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b57033604051806060016040528060405180608001604052808e60e00151600081518110610d2657610d266121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681526020018e6000015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60a0015165ffffffffffff1681526020018d6000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018c60a0015165ffffffffffff168152508a8060200190610dcc9190611fdb565b6040518563ffffffff1660e01b8152600401610deb9493929190612047565b600060405180830381600087803b158015610e0557600080fd5b505af1158015610e19573d6000803e3d6000fd5b505050505b60005b8581101561110f57600081600101905060008a60e001518281518110610e4957610e496121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168b60e001518481518110610e7d57610e7d6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16109050610f0a60405180606001604052808b81526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018d60e001518681518110610ee457610ee46121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250611435565b80156110015760008b61010001518481518110610f2957610f296121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c90526401000276a4606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190612109565b91505080610ff99061215c565b9950506110fc565b60008b6101000151848151811061101a5761101a6121a7565b60209081029190910101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481018c905273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482015273ffffffffffffffffffffffffffffffffffffffff9091169063128acb089060c40160408051808303816000875af11580156110c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ec9190612109565b5090506110f88161215c565b9950505b61110461159e565b503093509050610e21565b5061111e8689606001516115fe565b861015611157576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008860e00151868151811061116f5761116f6121a7565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156111e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112099190611fc2565b905081811080611221575061121e8783612194565b81105b15611258576040517f883d583b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61128e8960c001518a60e001518881518110611276576112766121a7565b60200260200101518b608001518c602001518b61162e565b965083156113dd577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810189905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505050506000896040015173ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114611397576040519150601f19603f3d011682016040523d82523d6000602084013e61139c565b606091505b50509050806113d7576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611429565b6114298960400151888b60e0015189815181106113fc576113fc6121a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166116ef9092919063ffffffff16565b50505050505092915050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103611493576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036115fc576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061271061160d83826121d6565b61161b9061ffff16856121f8565b611625919061220f565b90505b92915050565b60006107d061ffff85161115611679576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561168b575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156116c557606460328402046116c8565b60005b90508083038382146116e0576116e08a8a8484611781565b50505090910395945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261177c908490611886565b505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156117f15773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206117ef9085611995565b505b6117fb8186611995565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b60006118e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119b79092919063ffffffff16565b9050805160001480611909575080806020019051810190611909919061224a565b61177c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611670565b60006116258373ffffffffffffffffffffffffffffffffffffffff84166119ce565b60606119c68484600085611a1d565b949350505050565b6000818152600183016020526040812054611a1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611628565b506000611628565b606082471015611aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611670565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ad89190612297565b60006040518083038185875af1925050503d8060008114611b15576040519150601f19603f3d011682016040523d82523d6000602084013e611b1a565b606091505b5091509150611b2b87838387611b36565b979650505050505050565b60608315611bcc578251600003611bc55773ffffffffffffffffffffffffffffffffffffffff85163b611bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611670565b50816119c6565b6119c68383815115611be15781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167091906122b3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611c6857611c68611c15565b60405290565b604051610120810167ffffffffffffffff81118282101715611c6857611c68611c15565b803573ffffffffffffffffffffffffffffffffffffffff81168114611cb657600080fd5b919050565b803561ffff81168114611cb657600080fd5b803565ffffffffffff81168114611cb657600080fd5b600060408284031215611cf557600080fd5b50919050565b600080828403610160811215611d1057600080fd5b61014080821215611d2057600080fd5b611d28611c44565b9150611d3385611c92565b8252611d4160208601611c92565b6020830152611d5260408601611cbb565b6040830152611d6360608601611cbb565b606083015260808501356080830152611d7e60a08601611ccd565b60a0830152611d8f60c08601611c92565b60c0830152611da060e08601611c92565b60e08301526101008581013590830152610120611dbe818701611c92565b9083015290925083013567ffffffffffffffff811115611ddd57600080fd5b611de985828601611ce3565b9150509250929050565b600082601f830112611e0457600080fd5b8135602067ffffffffffffffff80831115611e2157611e21611c15565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611e6457611e64611c15565b604052938452858101830193838101925087851115611e8257600080fd5b83870191505b84821015611b2b57611e9982611c92565b83529183019190830190611e88565b60008060408385031215611ebb57600080fd5b823567ffffffffffffffff80821115611ed357600080fd5b908401906101208287031215611ee857600080fd5b611ef0611c6e565b8235815260208301356020820152611f0a60408401611c92565b6040820152611f1b60608401611cbb565b6060820152611f2c60808401611cbb565b6080820152611f3d60a08401611ccd565b60a0820152611f4e60c08401611c92565b60c082015260e083013582811115611f6557600080fd5b611f7188828601611df3565b60e0830152506101008084013583811115611f8b57600080fd5b611f9789828701611df3565b828401525050809450506020850135915080821115611fb557600080fd5b50611de985828601611ce3565b600060208284031215611fd457600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261201057600080fd5b83018035915067ffffffffffffffff82111561202b57600080fd5b60200191503681900382131561204057600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b6000806040838503121561211c57600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f8000000000000000000000000000000000000000000000000000000000000000820361218d5761218d61212d565b5060000390565b808201808211156116285761162861212d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff8281168282160390808211156121f1576121f161212d565b5092915050565b80820281158282048414176116285761162861212d565b600082612245577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561225c57600080fd5b8151801515811461226c57600080fd5b9392505050565b60005b8381101561228e578181015183820152602001612276565b50506000910152565b600082516122a9818460208701612273565b9190910192915050565b60208152600082518060208401526122d2816040850160208701612273565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212206470212c26401bfed45b0e055a2fec3538a012dd9b4a7c240649098c64b340f564736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/WarpLink.json b/packages/hardhat/deployments/polygon/WarpLink.json index 6eb8c3ad..37631f83 100644 --- a/packages/hardhat/deployments/polygon/WarpLink.json +++ b/packages/hardhat/deployments/polygon/WarpLink.json @@ -1,5 +1,5 @@ { - "address": "0x56b990b4909E916E1dA74294D8b67ED045402313", + "address": "0x8A49ad8741Bc81148852bE98985F700AC28B959b", "abi": [ { "inputs": [], @@ -16,11 +16,6 @@ "name": "DeadlineExpired", "type": "error" }, - { - "inputs": [], - "name": "EthNotSupportedForWarp", - "type": "error" - }, { "inputs": [ { @@ -34,17 +29,17 @@ }, { "inputs": [], - "name": "InconsistentPartPayerOut", + "name": "IllegalJumpInSplit", "type": "error" }, { "inputs": [], - "name": "InconsistentPartTokenOut", + "name": "InconsistentPartPayerOut", "type": "error" }, { "inputs": [], - "name": "IncorrectEthValue", + "name": "InconsistentPartTokenOut", "type": "error" }, { @@ -54,261 +49,63 @@ }, { "inputs": [], - "name": "InsufficientOutputAmount", + "name": "InsufficientEthValue", "type": "error" }, { "inputs": [], - "name": "InsufficientTokensDelivered", + "name": "InsufficientOutputAmount", "type": "error" }, { "inputs": [], - "name": "NotEnoughParts", + "name": "InsufficientTokensDelivered", "type": "error" }, { "inputs": [], - "name": "UnexpectedPayerForWrap", + "name": "JumpMustBeLastCommand", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForUnwrap", + "name": "NativeTokenNotSupported", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenForWrap", + "name": "NotEnoughParts", "type": "error" }, { "inputs": [], - "name": "UnexpectedTokenOut", + "name": "UnexpectedPayerForWrap", "type": "error" }, { "inputs": [], - "name": "UnexpectedValueAndTokenCombination", + "name": "UnexpectedTokenForUnwrap", "type": "error" }, { "inputs": [], - "name": "UnhandledCommand", + "name": "UnexpectedTokenForWrap", "type": "error" }, { "inputs": [], - "name": "UnhandledPoolKind", + "name": "UnexpectedTokenOut", "type": "error" }, { "inputs": [], - "name": "COMMAND_TYPE_SPLIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_UNWRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "COMMAND_TYPE_WRAP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeSplit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeUnwrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpCurveExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV2LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInput", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "commandTypeWarpUniV3LikeExactInputSingle", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledCommand", + "type": "error" }, { "inputs": [], - "name": "commandTypeWrap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" + "name": "UnhandledPoolKind", + "type": "error" }, { "inputs": [ @@ -393,44 +190,44 @@ "type": "function" } ], - "transactionHash": "0x3311991f6ff7f049c2de07cdcfd547a98f5e02ace1a9aeecd358ddf257e2b3ef", + "transactionHash": "0x920bea0ffa8f9acd809574b1588ff6395d482524878b07e2e02b952747994bc9", "receipt": { "to": null, "from": "0x67E21394bBC46c010D9B8DCf00172Ab7996964BE", - "contractAddress": "0x56b990b4909E916E1dA74294D8b67ED045402313", - "transactionIndex": 134, - "gasUsed": "3602947", - "logsBloom": "0x00000000000000000000000000000000000000010000000000000000040000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000202000000000000000000000000100000", - "blockHash": "0x91941b87b83a8cf0a727e7937d0b04467947083da7d2abfdddbb77532fc53011", - "transactionHash": "0x3311991f6ff7f049c2de07cdcfd547a98f5e02ace1a9aeecd358ddf257e2b3ef", + "contractAddress": "0x8A49ad8741Bc81148852bE98985F700AC28B959b", + "transactionIndex": 58, + "gasUsed": "3923320", + "logsBloom": "0x00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000040000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000120000000000000000000000000000000000000000000200000000000000000000000000100000", + "blockHash": "0x03b4aeca4576d5768e60d94a9a9cde88339d2c6bfe66414cbadbeea2bb2acf23", + "transactionHash": "0x920bea0ffa8f9acd809574b1588ff6395d482524878b07e2e02b952747994bc9", "logs": [ { - "transactionIndex": 134, - "blockNumber": 47792814, - "transactionHash": "0x3311991f6ff7f049c2de07cdcfd547a98f5e02ace1a9aeecd358ddf257e2b3ef", + "transactionIndex": 58, + "blockNumber": 47996424, + "transactionHash": "0x920bea0ffa8f9acd809574b1588ff6395d482524878b07e2e02b952747994bc9", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x00000000000000000000000067e21394bbc46c010d9b8dcf00172ab7996964be", - "0x000000000000000000000000ef46d5fe753c988606e6f703260d816af53b03eb" + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" ], - "data": "0x00000000000000000000000000000000000000000000000000d71d40990da0c900000000000000000000000000000000000000000000000549bc13a606425bb1000000000000000000000000000000000000000000000235de1ba5e57a9fd27900000000000000000000000000000000000000000000000548e4f6656d34bae8000000000000000000000000000000000000000000000235def2c32613ad7342", - "logIndex": 469, - "blockHash": "0x91941b87b83a8cf0a727e7937d0b04467947083da7d2abfdddbb77532fc53011" + "data": "0x000000000000000000000000000000000000000000000000000c2366b0d6c1580000000000000000000000000000000000000000000000053dda947796432cc90000000000000000000000000000000000000000000013e663f1aeda05ffa08e0000000000000000000000000000000000000000000000053dce7110e56c6b710000000000000000000000000000000000000000000013e663fdd240b6d661e6", + "logIndex": 192, + "blockHash": "0x03b4aeca4576d5768e60d94a9a9cde88339d2c6bfe66414cbadbeea2bb2acf23" } ], - "blockNumber": 47792814, - "cumulativeGasUsed": "19779196", + "blockNumber": 47996424, + "cumulativeGasUsed": "10826978", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "67dda12c87973688d0861d0d4554c2ee", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthNotSupportedForWarp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedValueAndTokenCombination\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_SPLIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_UNWRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COMMAND_TYPE_WRAP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeSplit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeUnwrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpCurveExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV2LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInput\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWarpUniV3LikeExactInputSingle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commandTypeWrap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ncontract WarpLink is IWarpLink {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct TransientState {\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n }\\n\\n uint256 public constant COMMAND_TYPE_WRAP = 1;\\n uint256 public constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 public constant COMMAND_TYPE_SPLIT = 4;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 public constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 public constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n\\n function commandTypeWrap() external pure returns (uint256) {\\n return COMMAND_TYPE_WRAP;\\n }\\n\\n function commandTypeUnwrap() external pure returns (uint256) {\\n return COMMAND_TYPE_UNWRAP;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeSplit() external pure returns (uint256) {\\n return COMMAND_TYPE_SPLIT;\\n }\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE;\\n }\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT;\\n }\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256) {\\n return COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert EthNotSupportedForWarp();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n if (params.tokenIn != address(0)) {\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n TransientState memory t;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (msg.value == 0) {\\n if (params.tokenIn == address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n } else {\\n if (params.tokenIn != address(0)) {\\n revert UnexpectedValueAndTokenCombination();\\n }\\n\\n if (msg.value != params.amountIn) {\\n revert IncorrectEthValue();\\n }\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd9e99e7f5322f064977ea54517ad3889c4b74b1828d18c79e0490e06e2295a09\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0xfb5c50a07ad96ae513307136ffe04217d19b0fd51b356de0fd41fdbc533ada2d\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error IncorrectEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedValueAndTokenCombination();\\n error UnexpectedPayerForWrap();\\n error EthNotSupportedForWarp();\\n error DeadlineExpired();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n\\n function commandTypeWrap() external pure returns (uint256);\\n\\n function commandTypeUnwrap() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeSplit() external pure returns (uint256);\\n\\n function commandTypeWarpUniV2LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInputSingle() external pure returns (uint256);\\n\\n function commandTypeWarpUniV3LikeExactInput() external pure returns (uint256);\\n\\n function commandTypeWarpCurveExactInputSingle() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa25e901022a1fc4f1bddb4e10cdce3a8963172ff1a8af9f4a2000ab0959876e7\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0xaffc1a168f2c37b152be57e0446aa1a368659bc714aeef098071561c08da967d\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0x295b919c3508c893139418d755ce977814ac7c7ed3c11cbdc2674ab3676620d8\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd03f388d813a30901dd729675044a62908385479236bb7070b32eb9dd84b7161\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x19a8596e093254d05b211efa62f40768ea69271b4dd6dabb73ce55971445d5bf\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9e63dcda853985801b3df5644808b3706b857fdb86e306267b0cb7dd347ea5ae\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x56dd69e4a79fe2ef5d0837327a9589985a1fb0a272b051e56f2c732fd9879374\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb71da75d7a54104f1dada9dd2255e533700e40e38852ca4c5da57951fbcf982c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0x06a8d86fd413ab2b56edda43181f090202ba86a59ec1d34172f359a57b50bcb5\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0xd91bb0f7d1c4adbe1d1a4ea0879b447382c8d13bd5dd47b0990c1f015357d7f3\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6c564dca55e92d9ee1c546a75a68d4e7c8799773f59f2aab4ea72cc70e601dff\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061409b806100206000396000f3fe60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", - "deployedBytecode": "0x60806040526004361061010e5760003560e01c8063cd98504c116100a5578063dc7b39db11610074578063e92a6f0511610059578063e92a6f0514610240578063eb2b767714610255578063fa31c9c01461026a57600080fd5b8063dc7b39db14610216578063e67cbdb81461022b57600080fd5b8063cd98504c146101c4578063cedf0d18146101d9578063d267733d146101ed578063dc76f8721461020257600080fd5b806391f46532116100e157806391f465321461017357806393a4c0cb14610187578063ad5d50261461019b578063b41e3c2c146101b057600080fd5b80632cad76e81461011357806344b14b811461013557806367ec524c1461014a57806372c30b061461015e575b600080fd5b34801561011f57600080fd5b5060085b60405190815260200160405180910390f35b34801561014157600080fd5b50610123600181565b34801561015657600080fd5b506007610123565b34801561016a57600080fd5b50610123600881565b34801561017f57600080fd5b506004610123565b34801561019357600080fd5b506003610123565b3480156101a757600080fd5b50610123600781565b3480156101bc57600080fd5b506006610123565b3480156101d057600080fd5b50610123600681565b3480156101e557600080fd5b506005610123565b3480156101f957600080fd5b50610123600281565b34801561020e57600080fd5b506002610123565b610229610224366004613b26565b61027e565b005b34801561023757600080fd5b50610123600381565b34801561024c57600080fd5b50610123600481565b34801561026157600080fd5b50610123600581565b34801561027657600080fd5b506001610123565b81610100015165ffffffffffff164211156102c5576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608082015173ffffffffffffffffffffffffffffffffffffffff1615610453577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280886080015173ffffffffffffffffffffffffffffffffffffffff1681526020018860c0015173ffffffffffffffffffffffffffffffffffffffff16815260200188610100015165ffffffffffff168152602001876000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200186610100015165ffffffffffff168152508480602001906104019190613c49565b6040518563ffffffff1660e01b81526004016104209493929190613cb5565b600060405180830381600087803b15801561043a57600080fd5b505af115801561044e573d6000803e3d6000fd5b505050505b60408051608080820183526000808352602083018190529282018381526060830184815260c087015184529186015173ffffffffffffffffffffffffffffffffffffffff16905261010085015165ffffffffffff1690529034900361050e57608083015173ffffffffffffffffffffffffffffffffffffffff16610503576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360208201526105a4565b608083015173ffffffffffffffffffffffffffffffffffffffff1615610560576040517fd34bde3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c00151341461059d576040517fab0a033b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3060208201525b60006105c9846101200151604080518082019091528181528151909101602082015290565b90506105d5818361073b565b8051604082015160a0870151929450909173ffffffffffffffffffffffffffffffffffffffff808316911614610637576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498660e00151876040015161087e565b821015610682576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61069f86600001518760a0015188602001518960e00151866108ac565b915073ffffffffffffffffffffffffffffffffffffffff811661070c57856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610706573d6000803e3d6000fd5b50610733565b60608601516107339073ffffffffffffffffffffffffffffffffffffffff8316908461096d565b505050505050565b60408051608081018252600080825260208201819052918101829052606081019190915260006107718480516001018051915290565b60ff16905060005b818110156108725760006107938680516001018051915290565b60ff169050600181036107b0576107a985610a46565b945061085f565b600281036107c1576107a985610bbd565b600381036107d3576107a98686610dc8565b600481036107e5576107a98686611334565b600581036107f7576107a986866115dc565b60068103610809576107a98686611d45565b6007810361081b576107a9868661220f565b6008810361082d576107a986866126e9565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b508061086a81613da6565b915050610779565b50829150505b92915050565b600061271061088d8382613dde565b61089b9061ffff1685613df9565b6108a59190613e3f565b9392505050565b60006107d061ffff851611156108f7576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b60008284811115610909575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156109435760646032840204610946565b60005b905080830383821461095e5761095e8a8a8484612ab0565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a419084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bb5565b505050565b604080516080810182526000808252602082018190528183018190526060820152908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610ada576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff163014610b2d576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff166040808501829052845181517fd0e30db0000000000000000000000000000000000000000000000000000000008152915163d0e30db09260048082019260009290919082900301818588803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50959695505050505050565b6040805160808101825260008082526020820181905281830181905260608201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e108054928401519192909173ffffffffffffffffffffffffffffffffffffffff918216911614610c5a576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610c86573060208601525b600060408601528015610d34576001830154855184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610d1b57600080fd5b505af1158015610d2f573d6000803e3d6000fd5b505050505b825485516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610d8d9160040190815260200190565b600060405180830381600087803b158015610da757600080fd5b505af1158015610dbb573d6000803e3d6000fd5b5096979650505050505050565b6040805160808101825260008082526020820181905281830181905260608201529082015173ffffffffffffffffffffffffffffffffffffffff16610e39576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260208301513073ffffffffffffffffffffffffffffffffffffffff90911603610f2257602081015183516040850151610f1d9273ffffffffffffffffffffffffffffffffffffffff9091169161096d565b610ff7565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460208481015190830151855160408088015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610fd857600080fd5b505af1158015610fec573d6000803e3d6000fd5b505030602086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d9190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826040015161109d57905b6060830151855161ffff61271092830316918402908202908101908302816110c7576110c7613e10565b0486525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190613ee8565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f856040015161118f578751611192565b60005b86604001516111a25760006111a5565b88515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa158015611297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190613ee8565b9050818110806112d5575086516112d29083613f01565b81105b1561130c576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff16604085015250919392505050565b604080516080810182526000808252602082018190529181018290526060810191909152600061136a8480516001018051915290565b835160ff919091169150600060028310156113b1576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b858110156115ad5760006113cc600188613f14565b82106113d85785611405565b6127106113eb8b80516002018051915290565b8a516113fb9161ffff1690613df9565b6114059190613e3f565b905085811115611441576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61144b8187613f14565b60408051608081018252600060208083018281528385018381526060850193909352868452908e015173ffffffffffffffffffffffffffffffffffffffff908116909152928d01519092169091529096506114a68b8261073b565b9050826000036114c3578060200151935080604001519450611595565b8473ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff161461152c576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614611595576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115a19087613f01565b955050506001016113b7565b5073ffffffffffffffffffffffffffffffffffffffff9081166020880152166040860152845250919392505050565b60408051608081018252600080825260208201819052918101829052606081019190915261162460405180606001604052806060815260200160608152602001606081525090565b60006116368580516001018051915290565b60ff169050611646816001613f01565b67ffffffffffffffff81111561165e5761165e6139b9565b604051908082528060200260200182016040528015611687578160200160208202803683370190505b50808352604085015181519091906000906116a4576116a4613f27565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b8181101561173d57855160140180519087528351611700836001613f01565b8151811061171057611710613f27565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116e1565b506117488582612cc4565b60208301526117578582612d66565b604083015281518051600091908390811061177457611774613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180e9190613ee8565b9050600061182e8460400151876000015186600001518760200151612def565b90503073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff16036118bd576118b8846020015160008151811061188157611881613f27565b60200260200101518760000151886040015173ffffffffffffffffffffffffffffffffffffffff1661096d9092919063ffffffff16565b6119cb565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460208781015190860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061191b5761191b613f27565b602090810291909101015189516040808c015190517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152919091166064820152608401600060405180830381600087803b1580156119ac57600080fd5b505af11580156119c0573d6000803e3d6000fd5b505030602089015250505b60005b83811015611bcf5760006119e3826001613f01565b90506000866000015182815181106119fd576119fd613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a3157611a31613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a5b576000611a5e565b60015b905060006002886000015151611a749190613f14565b8410611a805730611a9f565b87602001518381518110611a9657611a96613f27565b60200260200101515b905087602001518481518110611ab757611ab7613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611afe57868581518110611af157611af1613f27565b6020026020010151611b01565b60005b84611b0d576000611b28565b878681518110611b1f57611b1f613f27565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba857600080fd5b505af1158015611bbc573d6000803e3d6000fd5b5050600190950194506119ce9350505050565b50600084600001518481518110611be857611be8613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c829190613ee8565b90508160018351611c939190613f14565b81518110611ca357611ca3613f27565b6020908102919091010151875282811080611cc857508651611cc59084613f01565b81105b15611cff576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1357611d13613f27565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff16604088015250949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff9081166020830152604084015116611e12576040517f767836b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea49190613ee8565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16109050611f3c604051806060016040528087600001518152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff16815250613024565b801561201857602083015185516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190613f56565b9150508061201090613f7a565b8652506120f8565b602083015185516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af11580156120c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e89190613f56565b5090506120f481613f7a565b8652505b61210061318d565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561216e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121929190613ee8565b9050828110806121ac575085516121a99084613f01565b81105b156121e3576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660408401525050306020820152919050565b60408051608081018252600080825260208201819052918101829052606081019190915261225760405180606001604052806060815260200160608152602001606081525090565b60006122698580516001018051915290565b60ff1690506122788582612cc4565b82526122848582612cc4565b60208301528151600090612299600184613f14565b815181106122a9576122a9613f27565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015612324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123489190613ee8565b905060005b838110156125f6576000811561238757855161236a600184613f14565b8151811061237a5761237a613f27565b602002602001015161238d565b87604001515b9050856000015182815181106123a5576123a5613f27565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff9081166040808c0182905280516060810182528c5181528c85015184169481019490945291841691830182905211906123fe90613024565b8260000361240d573060208a01525b60008760200151848151811061242557612425613f27565b6020026020010151905081156125075789516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152831515602482015260448101919091526401000276a4606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190613f56565b915050806124ff90613f7a565b8b52506125e3565b89516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528315156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d25606482015260a06084820152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af11580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613f56565b5090506125df81613f7a565b8b52505b6125eb61318d565b50505060010161234d565b5060408087015190517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268c9190613ee8565b9050818110806126a6575086516126a39083613f01565b81105b156126dd576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260408301518151602085015173ffffffffffffffffffffffffffffffffffffffff92831615929182161591309116146128d2577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10600101546020860151865160408089015190517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505030602088015250505b60008161296f5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296a9190613ee8565b612971565b475b9050826129a6576020840151865160408801516129a69273ffffffffffffffffffffffffffffffffffffffff909116916131ed565b6129da84608001518560a001518660200151866129c45760006129c7565b89515b604089015160608a01518c5160006132e3565b600082612a775784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a729190613ee8565b612a79565b475b855173ffffffffffffffffffffffffffffffffffffffff1660408901529050612aa28282613f14565b875250949695505050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff841615612b205773ffffffffffffffffffffffffffffffffffffffff851660009081526002820160205260409020612b1e9085613678565b505b612b2a8186613678565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000612c17826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661369a9092919063ffffffff16565b9050805160001480612c38575080806020019051810190612c389190613fb2565b610a41576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ee565b60608167ffffffffffffffff811115612cdf57612cdf6139b9565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b82811015612d5f5783516014018051908552828281518110612d3257612d32613f27565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101612d0e565b5092915050565b60608167ffffffffffffffff811115612d8157612d816139b9565b604051908082528060200260200182016040528015612daa578160200160208202803683370190505b50905060005b82811015612d5f5783516002018051908552828281518110612dd457612dd4613f27565b61ffff90921660209283029190910190910152600101612db0565b805182516060919067ffffffffffffffff811115612e0f57612e0f6139b9565b604051908082528060200260200182016040528015612e38578160200160208202803683370190505b5091508482600081518110612e4f57612e4f613f27565b60200260200101818152505060005b8181101561301a576000858281518110612e7a57612e7a613f27565b60200260200101519050600086836001612e949190613f01565b81518110612ea457612ea4613f27565b602002602001015190506000898481518110612ec257612ec2613f27565b6020026020010151612710612ed79190613dde565b61ffff169050600080888681518110612ef257612ef2613f27565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190613e98565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161115612fc357905b828b0282612710020181848d020281612fde57612fde613e10565b049a508a88612fee886001613f01565b81518110612ffe57612ffe613f27565b6020908102919091010152505060019093019250612e5e915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613082576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff166001036131eb576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905261327984826136b1565b6132dd5760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526132d39085907f095ea7b300000000000000000000000000000000000000000000000000000000906064016109bf565b6132dd8482612bb5565b50505050565b8760ff1660010361341157861561339c576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561337e57600080fd5b505af1158015613392573d6000803e3d6000fd5b505050505061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613365565b8760ff166002036135515786156134dc576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156134b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906134d69190613ee8565b5061366e565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df02124908790608401613493565b8760ff1660030361363c5786156135cf576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b908790608401613493565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b908908790608401613493565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006108a58373ffffffffffffffffffffffffffffffffffffffff8416613772565b60606136a984846000856137c1565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff16846040516136db9190613ff8565b6000604051808303816000865af19150503d8060008114613718576040519150601f19603f3d011682016040523d82523d6000602084013e61371d565b606091505b50915091508180156137475750805115806137475750808060200190518101906137479190613fb2565b8015613769575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b60008181526001830160205260408120546137b957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610878565b506000610878565b606082471015613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ee565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161387c9190613ff8565b60006040518083038185875af1925050503d80600081146138b9576040519150601f19603f3d011682016040523d82523d6000602084013e6138be565b606091505b50915091506138cf878383876138da565b979650505050505050565b606083156139705782516000036139695773ffffffffffffffffffffffffffffffffffffffff85163b613969576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ee565b50816136a9565b6136a983838151156139855781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee9190614014565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613a0c57613a0c6139b9565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613a3657600080fd5b919050565b803561ffff81168114613a3657600080fd5b803565ffffffffffff81168114613a3657600080fd5b600082601f830112613a7457600080fd5b813567ffffffffffffffff80821115613a8f57613a8f6139b9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613ad557613ad56139b9565b81604052838152866020858801011115613aee57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060408284031215613b2057600080fd5b50919050565b60008060408385031215613b3957600080fd5b823567ffffffffffffffff80821115613b5157600080fd5b908401906101408287031215613b6657600080fd5b613b6e6139e8565b613b7783613a12565b8152613b8560208401613a3b565b6020820152613b9660408401613a3b565b6040820152613ba760608401613a12565b6060820152613bb860808401613a12565b6080820152613bc960a08401613a12565b60a082015260c083013560c082015260e083013560e0820152610100613bf0818501613a4d565b908201526101208381013583811115613c0857600080fd5b613c1489828701613a63565b828401525050809450506020850135915080821115613c3257600080fd5b50613c3f85828601613b0e565b9150509250929050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c7e57600080fd5b83018035915067ffffffffffffffff821115613c9957600080fd5b602001915036819003821315613cae57600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dd757613dd7613d77565b5060010190565b61ffff828116828216039080821115612d5f57612d5f613d77565b808202811582820484141761087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613e75577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613a3657600080fd5b600080600060608486031215613ead57600080fd5b613eb684613e7a565b9250613ec460208501613e7a565b9150604084015163ffffffff81168114613edd57600080fd5b809150509250925092565b600060208284031215613efa57600080fd5b5051919050565b8082018082111561087857610878613d77565b8181038181111561087857610878613d77565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215613f6957600080fd5b505080516020909101519092909150565b60007f80000000000000000000000000000000000000000000000000000000000000008203613fab57613fab613d77565b5060000390565b600060208284031215613fc457600080fd5b815180151581146108a557600080fd5b60005b83811015613fef578181015183820152602001613fd7565b50506000910152565b6000825161400a818460208701613fd4565b9190910192915050565b6020815260008251806020840152614033816040850160208701613fd4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212205309891b9d7f52fb5ac1515108e4fa9d95d02adf4d52127c5e5fe98ccb0f93e664736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "df6263755b6a66e75866b356448256e7", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"CallbackAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CallbackStillActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maxFeeBps\",\"type\":\"uint16\"}],\"name\":\"FeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IllegalJumpInSplit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartPayerOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentPartTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAmountRemaining\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientTokensDelivered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"JumpMustBeLastCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughParts\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedPayerForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForUnwrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenForWrap\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenOut\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledCommand\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnhandledPoolKind\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"partner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"feeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"slippageBps\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOut\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"deadline\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"commands\",\"type\":\"bytes\"}],\"internalType\":\"struct IWarpLink.Params\",\"name\":\"params\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct PermitParams\",\"name\":\"permit\",\"type\":\"tuple\"}],\"name\":\"warpLinkEngage\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"errors\":{\"FeeTooHigh(uint16)\":[{\"notice\":\"The swap fee is over the maximum allowed\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/facets/WarpLink.sol\":\"WarpLink\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[\":@openzeppelin/=@openzeppelin/\",\":@uniswap/=@uniswap/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\",\":hardhat-deploy/=hardhat-deploy/\",\":hardhat/=hardhat/\",\":solidity-stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\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 /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```solidity\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n *\\n * [WARNING]\\n * ====\\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\\n * unusable.\\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\\n *\\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\\n * array of EnumerableSet.\\n * ====\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastValue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastValue;\\n // Update the index for the moved value\\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n bytes32[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n /// @solidity memory-safe-assembly\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9f4357008a8f7d8c8bf5d48902e789637538d8c016be5766610901b4bba81514\",\"license\":\"MIT\"},\"@uniswap/v2-periphery/contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n function transfer(address to, uint value) external returns (bool);\\n function withdraw(uint) external;\\n}\\n\",\"keccak256\":\"0xfc10758fd8dba790c39468dccd358cb7cef06ae7c4781832cc7aa76f91f167e6\"},\"contracts/facets/WarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {LibWarp} from '../libraries/LibWarp.sol';\\nimport {LibKitty} from '../libraries/LibKitty.sol';\\nimport {Stream} from '../libraries/Stream.sol';\\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\\nimport {LibCurve} from '../libraries/LibCurve.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nabstract contract WarpLinkCommandTypes {\\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\\n}\\n\\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\\n using SafeERC20 for IERC20;\\n using Stream for uint256;\\n\\n struct WarpUniV2LikeWarpSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpUniV2LikeExactInputParams {\\n // NOTE: Excluding the first token\\n address[] tokens;\\n address[] pools;\\n uint16[] poolFeesBps;\\n }\\n\\n struct WarpUniV3LikeExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n bool zeroForOne; // tokenIn < tokenOut\\n uint16 poolFeeBps;\\n }\\n\\n struct WarpCurveExactInputSingleParams {\\n address tokenOut;\\n address pool;\\n uint8 tokenIndexIn;\\n uint8 tokenIndexOut;\\n uint8 kind;\\n bool underlying;\\n }\\n\\n struct JumpStargateParams {\\n uint16 dstChainId;\\n uint256 srcPoolId;\\n uint256 dstPoolId;\\n }\\n\\n struct TransientState {\\n address paramPartner;\\n uint16 paramFeeBps;\\n address paramRecipient;\\n uint256 paramAmountOut;\\n uint16 paramSlippageBps;\\n uint256 amount;\\n address payer;\\n address token;\\n uint48 deadline;\\n /**\\n * 0 or 1\\n */\\n uint256 jumped;\\n /**\\n * The amount of native value not spent. The native value starts off as\\n * `msg.value - params.amount` and is decreased by spending money on jumps.\\n *\\n * Any leftover native value is returned to `msg.sender`\\n */\\n uint256 nativeValueRemaining;\\n }\\n\\n function processSplit(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 parts = stream.readUint8();\\n uint256 amountRemaining = t.amount;\\n uint256 amountOutSum;\\n\\n if (parts < 2) {\\n revert NotEnoughParts();\\n }\\n\\n // Store the token out for the previous part to ensure every part has the same output token\\n address firstPartTokenOut;\\n address firstPartPayerOut;\\n\\n for (uint256 partIndex; partIndex < parts; ) {\\n // TODO: Unchecked?\\n // For the last part, use the remaining amount. Else read the % from the stream\\n uint256 partAmount = partIndex < parts - 1\\n ? (t.amount * stream.readUint16()) / 10_000\\n : amountRemaining;\\n\\n if (partAmount > amountRemaining) {\\n revert InsufficientAmountRemaining();\\n }\\n\\n amountRemaining -= partAmount;\\n\\n TransientState memory tPart;\\n\\n tPart.amount = partAmount;\\n tPart.payer = t.payer;\\n tPart.token = t.token;\\n\\n tPart = engageInternal(stream, tPart);\\n\\n if (tPart.jumped == 1) {\\n revert IllegalJumpInSplit();\\n }\\n\\n if (partIndex == 0) {\\n firstPartPayerOut = tPart.payer;\\n firstPartTokenOut = tPart.token;\\n } else {\\n if (tPart.token != firstPartTokenOut) {\\n revert InconsistentPartTokenOut();\\n }\\n\\n if (tPart.payer != firstPartPayerOut) {\\n revert InconsistentPartPayerOut();\\n }\\n }\\n\\n // NOTE: Checked\\n amountOutSum += tPart.amount;\\n\\n unchecked {\\n partIndex++;\\n }\\n }\\n\\n t.payer = firstPartPayerOut;\\n t.token = firstPartTokenOut;\\n t.amount = amountOutSum;\\n\\n return t;\\n }\\n\\n /**\\n * Wrap ETH into WETH using the WETH contract\\n *\\n * The ETH must already be in this contract\\n *\\n * The next token will be WETH, with the amount and payer unchanged\\n */\\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(0)) {\\n revert UnexpectedTokenForWrap();\\n }\\n\\n if (t.payer != address(this)) {\\n // It's not possible to move a user's ETH\\n revert UnexpectedPayerForWrap();\\n }\\n\\n t.token = address(s.weth);\\n\\n s.weth.deposit{value: t.amount}();\\n\\n return t;\\n }\\n\\n /**\\n * Unwrap WETH into ETH using the WETH contract\\n *\\n * The payer can be the sender or this contract. After this operation, the\\n * token will be ETH (0) and the amount will be unchanged. The next payer\\n * will be this contract.\\n */\\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\\n LibWarp.State storage s = LibWarp.state();\\n\\n if (t.token != address(s.weth)) {\\n revert UnexpectedTokenForUnwrap();\\n }\\n\\n address prevPayer = t.payer;\\n bool shouldMoveTokensFirst = prevPayer != address(this);\\n\\n if (shouldMoveTokensFirst) {\\n t.payer = address(this);\\n }\\n\\n t.token = address(0);\\n\\n if (shouldMoveTokensFirst) {\\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\\n }\\n\\n s.weth.withdraw(t.amount);\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V2-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n * - zeroForOne (0 or 1, uint8)\\n * - poolFeeBps (uint16)\\n */\\n function processWarpUniV2LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n WarpUniV2LikeWarpSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.zeroForOne = stream.readUint8() == 1;\\n params.poolFeeBps = stream.readUint16();\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens to the pool\\n IERC20(t.token).safeTransfer(params.pool, t.amount);\\n } else {\\n // Transfer tokens from the sender to the pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\\n\\n if (!params.zeroForOne) {\\n // Token in > token out\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n // For 30 bps, multiply by 997\\n uint256 feeFactor = 10_000 - params.poolFeeBps;\\n\\n t.amount =\\n ((t.amount * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (t.amount * feeFactor));\\n }\\n\\n // NOTE: This check can be avoided if the factory is trusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n IUniswapV2Pair(params.pool).swap(\\n params.zeroForOne ? 0 : t.amount,\\n params.zeroForOne ? t.amount : 0,\\n address(this),\\n ''\\n );\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V2-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\\n */\\n function processWarpUniV2LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n params.tokens = new address[](poolLength + 1);\\n\\n // The params will contain all tokens including the first to remain compatible\\n // with the LibUniV2Like library's getAmountsOut function\\n params.tokens[0] = t.token;\\n\\n for (uint256 index; index < poolLength; ) {\\n params.tokens[index + 1] = stream.readAddress();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n params.pools = stream.readAddresses(poolLength);\\n params.poolFeesBps = stream.readUint16s(poolLength);\\n\\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\\n params.poolFeesBps,\\n t.amount,\\n params.tokens,\\n params.pools\\n );\\n\\n if (t.payer == address(this)) {\\n // Transfer tokens from this contract to the first pool\\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\\n } else {\\n // Transfer tokens from the sender to the first pool\\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Same as UniV2Like\\n for (uint index; index < poolLength; ) {\\n uint256 indexPlusOne = index + 1;\\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\\n\\n IUniswapV2Pair(params.pools[index]).swap(\\n zeroForOne ? 0 : amounts[indexPlusOne],\\n zeroForOne ? amounts[indexPlusOne] : 0,\\n to,\\n ''\\n );\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\\n\\n t.amount = amounts[amounts.length - 1];\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokens[poolLength];\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Uniswap V3-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpUniV3LikeExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV3LikeExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n\\n if (t.token == address(0)) {\\n revert NativeTokenNotSupported();\\n }\\n\\n // NOTE: The pool is untrusted\\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n bool zeroForOne = t.token < params.tokenOut;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\\n );\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n t.token = params.tokenOut;\\n\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n\\n return t;\\n }\\n\\n /**\\n * Warp multiple tokens in a series of Uniswap V3-like pools\\n *\\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\\n * before the first swap and after the last swap to ensure the correct amount\\n * was delivered.\\n *\\n * The payer can be the sender or this contract. The token must not be ETH (0).\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the last swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - pool length (uint8)\\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\\n * - pools (address 0, address 1, address pool length - 1)\\n */\\n function processWarpUniV3LikeExactInput(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpUniV2LikeExactInputParams memory params;\\n\\n uint256 poolLength = stream.readUint8();\\n\\n // The first token is not included\\n params.tokens = stream.readAddresses(poolLength);\\n params.pools = stream.readAddresses(poolLength);\\n\\n address lastToken = params.tokens[poolLength - 1];\\n\\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\\n\\n for (uint index; index < poolLength; ) {\\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\\n t.token = params.tokens[index];\\n bool zeroForOne = tokenIn < t.token;\\n\\n LibUniV3Like.beforeCallback(\\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\\n );\\n\\n if (index == 0) {\\n // Update the payer to this contract\\n // TODO: Compare check-and-set vs set\\n t.payer = address(this);\\n }\\n\\n address pool = params.pools[index];\\n\\n if (zeroForOne) {\\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MIN_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n } else {\\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\\n address(this),\\n zeroForOne,\\n int256(t.amount),\\n LibUniV3Like.MAX_SQRT_RATIO,\\n ''\\n );\\n\\n t.amount = uint256(-amountOutSigned);\\n }\\n\\n LibUniV3Like.afterCallback();\\n\\n unchecked {\\n index++;\\n }\\n }\\n\\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\\n\\n if (\\n // TOOD: Is this overflow check necessary?\\n nextTokenOutBalance < tokenOutBalancePrev ||\\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\\n ) {\\n revert InsufficientTokensDelivered();\\n }\\n\\n return t;\\n }\\n\\n /**\\n * Warp a single token in a Curve-like pool\\n *\\n * Since the pool is not trusted, the amount out is checked before\\n * and after the swap to ensure the correct amount was delivered.\\n *\\n * The payer can be the sender or this contract. The token may be ETH (0)\\n *\\n * After this operation, the token will be `params.tokenOut` and the amount will\\n * be the output of the swap. The next payer will be this contract.\\n *\\n * Params are read from the stream as:\\n * - tokenOut (address)\\n * - pool (address)\\n */\\n function processWarpCurveExactInputSingle(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n WarpCurveExactInputSingleParams memory params;\\n\\n params.tokenOut = stream.readAddress();\\n params.pool = stream.readAddress();\\n params.tokenIndexIn = stream.readUint8();\\n params.tokenIndexOut = stream.readUint8();\\n params.kind = stream.readUint8();\\n params.underlying = stream.readUint8() == 1;\\n\\n // NOTE: The pool is untrusted\\n bool isFromEth = t.token == address(0);\\n bool isToEth = params.tokenOut == address(0);\\n\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n uint256 balancePrev = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n if (!isFromEth) {\\n // TODO: Is this necessary to support USDT?\\n IERC20(t.token).forceApprove(params.pool, t.amount);\\n }\\n\\n LibCurve.exchange({\\n kind: params.kind,\\n underlying: params.underlying,\\n pool: params.pool,\\n eth: isFromEth ? t.amount : 0,\\n i: params.tokenIndexIn,\\n j: params.tokenIndexOut,\\n dx: t.amount,\\n // NOTE: There is no need to set a min out since the balance will be verified\\n min_dy: 0\\n });\\n\\n uint256 balanceNext = isToEth\\n ? address(this).balance\\n : IERC20(params.tokenOut).balanceOf(address(this));\\n\\n t.token = params.tokenOut;\\n t.amount = balanceNext - balancePrev;\\n\\n return t;\\n }\\n\\n /**\\n * Jump to another chain using the Stargate bridge\\n *\\n * The token must not be ETH (0)\\n *\\n * After this operation, the token will be unchanged and `t.amount` will\\n * be how much was sent. `t.jumped` will be set to `1` to indicate\\n * that no more commands should be run\\n *\\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\\n * because only `t.token` can be moved by Stargate.\\n *\\n * This command must not run inside of a split.\\n *\\n * A bridge fee must be paid in the native token. This fee is determined with\\n * `IStargateRouter.quoteLayerZeroFee`\\n *\\n * The value for `t.token` remains the same and is not chained.\\n *\\n * Params are read from the stream as:\\n * - dstChainId (uint16)\\n * - srcPoolId (uint8)\\n * - dstPoolId (uint8)\\n */\\n function processJumpStargate(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n if (t.token == address(0)) {\\n // NOTE: There is a WETH pool\\n revert NativeTokenNotSupported();\\n }\\n\\n JumpStargateParams memory params;\\n params.dstChainId = stream.readUint16();\\n params.srcPoolId = stream.readUint8();\\n params.dstPoolId = stream.readUint8();\\n\\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\\n // is never charged\\n t.amount = LibKitty.calculateAndRegisterFee(\\n t.paramPartner,\\n t.token,\\n t.paramFeeBps,\\n t.amount,\\n t.amount\\n );\\n\\n // Enforce minimum amount/max slippage\\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.token != address(0)) {\\n if (t.payer != address(this)) {\\n // Transfer tokens from the sender to this contract\\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\\n\\n // Update the payer to this contract\\n t.payer = address(this);\\n }\\n\\n // Allow Stargate to transfer the tokens\\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\\n }\\n\\n t.jumped = 1;\\n\\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\\n _dstChainId: params.dstChainId,\\n _srcPoolId: params.srcPoolId,\\n _dstPoolId: params.dstPoolId,\\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\\n _refundAddress: payable(address(this)),\\n _amountLD: t.amount,\\n // Max 5% slippage\\n _minAmountLD: (t.amount * 95) / 100,\\n _lzTxParams: IStargateRouter.lzTxObj({\\n dstGasForCall: 0,\\n dstNativeAmount: 0,\\n dstNativeAddr: ''\\n }),\\n _to: abi.encodePacked(t.paramRecipient),\\n _payload: ''\\n });\\n\\n t.nativeValueRemaining = 0;\\n\\n return t;\\n }\\n\\n function engageInternal(\\n uint256 stream,\\n TransientState memory t\\n ) internal returns (TransientState memory) {\\n uint256 commandCount = stream.readUint8();\\n\\n // TODO: End of stream check?\\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\\n // TODO: Unchecked?\\n uint256 commandType = stream.readUint8();\\n\\n if (commandType == COMMAND_TYPE_WRAP) {\\n t = processWrap(t);\\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\\n t = processUnwrap(t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV2LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_SPLIT) {\\n t = processSplit(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\\n t = processWarpUniV2LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\\n t = processWarpUniV3LikeExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\\n t = processWarpUniV3LikeExactInput(stream, t);\\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\\n t = processWarpCurveExactInputSingle(stream, t);\\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\\n if (commandIndex != commandCount - 1) {\\n revert JumpMustBeLastCommand();\\n }\\n\\n t = processJumpStargate(stream, t);\\n } else {\\n revert UnhandledCommand();\\n }\\n }\\n\\n return t;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\\n if (block.timestamp > params.deadline) {\\n revert DeadlineExpired();\\n }\\n\\n TransientState memory t;\\n t.paramPartner = params.partner;\\n t.paramFeeBps = params.feeBps;\\n t.paramRecipient = params.recipient;\\n t.paramAmountOut = params.amountOut;\\n t.amount = params.amountIn;\\n t.token = params.tokenIn;\\n t.deadline = params.deadline;\\n\\n if (params.tokenIn == address(0)) {\\n if (msg.value < params.amountIn) {\\n revert InsufficientEthValue();\\n }\\n\\n t.nativeValueRemaining = msg.value - params.amountIn;\\n\\n // The ETH has already been moved to this contract\\n t.payer = address(this);\\n } else {\\n // Tokens will initially moved from the sender\\n t.payer = msg.sender;\\n\\n t.nativeValueRemaining = msg.value;\\n\\n // Permit tokens / set allowance\\n LibWarp.state().permit2.permit(\\n msg.sender,\\n IAllowanceTransfer.PermitSingle({\\n details: IAllowanceTransfer.PermitDetails({\\n token: params.tokenIn,\\n amount: (uint160)(params.amountIn),\\n expiration: (uint48)(params.deadline),\\n nonce: (uint48)(permit.nonce)\\n }),\\n spender: address(this),\\n sigDeadline: (uint256)(params.deadline)\\n }),\\n permit.signature\\n );\\n }\\n\\n uint256 stream = Stream.createStream(params.commands);\\n\\n t = engageInternal(stream, t);\\n\\n uint256 amountOut = t.amount;\\n address tokenOut = t.token;\\n\\n if (tokenOut != params.tokenOut) {\\n revert UnexpectedTokenOut();\\n }\\n\\n // Enforce minimum amount/max slippage\\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\\n revert InsufficientOutputAmount();\\n }\\n\\n if (t.nativeValueRemaining > 0) {\\n // TODO: Is this the correct recipient?\\n payable(msg.sender).transfer(t.nativeValueRemaining);\\n }\\n\\n if (t.jumped == 1) {\\n // The coins have jumped away from this chain. Fees were collected before the jump\\n return;\\n }\\n\\n // Collect fees\\n amountOut = LibKitty.calculateAndRegisterFee(\\n params.partner,\\n params.tokenOut,\\n params.feeBps,\\n params.amountOut,\\n amountOut\\n );\\n\\n // Deliver tokens\\n if (tokenOut == address(0)) {\\n payable(params.recipient).transfer(amountOut);\\n } else {\\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0be7a956a725d437c18e3bc2a96f09804a20c04d17feac9ac895b503152c13e2\",\"license\":\"MIT\"},\"contracts/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x2542d3d1dc26be46c0c298c6c7a1ac7943fd920dd2ac7cc013fe775e36ba973a\",\"license\":\"MIT\"},\"contracts/interfaces/IUniV3Callback.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniV3Callback {\\n error CallbackInactive();\\n}\\n\",\"keccak256\":\"0x0a70c7deeb178bc6724fb3f2ff087eee95cb4e7779ed7bf8045a0dde1d2200dd\",\"license\":\"MIT\"},\"contracts/interfaces/IWarpLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {PermitParams} from '../libraries/PermitParams.sol';\\n\\ninterface IWarpLink {\\n error UnhandledCommand();\\n error InsufficientEthValue();\\n error InsufficientOutputAmount();\\n error InsufficientTokensDelivered();\\n error UnexpectedTokenForWrap();\\n error UnexpectedTokenForUnwrap();\\n error UnexpectedTokenOut();\\n error InsufficientAmountRemaining();\\n error NotEnoughParts();\\n error InconsistentPartTokenOut();\\n error InconsistentPartPayerOut();\\n error UnexpectedPayerForWrap();\\n error NativeTokenNotSupported();\\n error DeadlineExpired();\\n error IllegalJumpInSplit();\\n error JumpMustBeLastCommand();\\n\\n struct Params {\\n address partner;\\n uint16 feeBps;\\n /**\\n * How much below `amountOut` the user will accept\\n */\\n uint16 slippageBps;\\n address recipient;\\n address tokenIn;\\n address tokenOut;\\n uint256 amountIn;\\n /**\\n * The amount the user was quoted\\n */\\n uint256 amountOut;\\n uint48 deadline;\\n bytes commands;\\n }\\n\\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\\n}\\n\",\"keccak256\":\"0x9242d5352942101b05bea1dcaea4b057473c4c2ae65214618f5361a18e194daa\",\"license\":\"MIT\"},\"contracts/interfaces/external/IAllowanceTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title AllowanceTransfer\\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface IAllowanceTransfer is IEIP712 {\\n /// @notice Thrown when an allowance on a token has expired.\\n /// @param deadline The timestamp at which the allowed amount is no longer valid\\n error AllowanceExpired(uint256 deadline);\\n\\n /// @notice Thrown when an allowance on a token has been depleted.\\n /// @param amount The maximum amount allowed\\n error InsufficientAllowance(uint256 amount);\\n\\n /// @notice Thrown when too many nonces are invalidated.\\n error ExcessiveInvalidation();\\n\\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\\n event NonceInvalidation(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint48 newNonce,\\n uint48 oldNonce\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\\n event Approval(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration\\n );\\n\\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\\n event Permit(\\n address indexed owner,\\n address indexed token,\\n address indexed spender,\\n uint160 amount,\\n uint48 expiration,\\n uint48 nonce\\n );\\n\\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\\n event Lockdown(address indexed owner, address token, address spender);\\n\\n /// @notice The permit data for a token\\n struct PermitDetails {\\n // ERC20 token address\\n address token;\\n // the maximum amount allowed to spend\\n uint160 amount;\\n // timestamp at which a spender's token allowances become invalid\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice The permit message signed for a single token allownce\\n struct PermitSingle {\\n // the permit data for a single token alownce\\n PermitDetails details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The permit message signed for multiple token allowances\\n struct PermitBatch {\\n // the permit data for multiple token allowances\\n PermitDetails[] details;\\n // address permissioned on the allowed tokens\\n address spender;\\n // deadline on the permit signature\\n uint256 sigDeadline;\\n }\\n\\n /// @notice The saved permissions\\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n struct PackedAllowance {\\n // amount allowed\\n uint160 amount;\\n // permission expiry\\n uint48 expiration;\\n // an incrementing value indexed per owner,token,and spender for each signature\\n uint48 nonce;\\n }\\n\\n /// @notice A token spender pair.\\n struct TokenSpenderPair {\\n // the token the spender is approved\\n address token;\\n // the spender address\\n address spender;\\n }\\n\\n /// @notice Details for a token transfer.\\n struct AllowanceTransferDetails {\\n // the owner of the token\\n address from;\\n // the recipient of the token\\n address to;\\n // the amount of the token\\n uint160 amount;\\n // the token to be transferred\\n address token;\\n }\\n\\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\\n function allowance(\\n address user,\\n address token,\\n address spender\\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\\n\\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\\n /// @param token The token to approve\\n /// @param spender The spender address to approve\\n /// @param amount The approved amount of the token\\n /// @param expiration The timestamp at which the approval is no longer valid\\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\\n\\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(\\n address owner,\\n PermitSingle memory permitSingle,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\\n /// @param owner The owner of the tokens being approved\\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\\n /// @param signature The owner's signature over the permit data\\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\\n\\n /// @notice Transfer approved tokens from one address to another\\n /// @param from The address to transfer from\\n /// @param to The address of the recipient\\n /// @param amount The amount of the token to transfer\\n /// @param token The token address to transfer\\n /// @dev Requires the from address to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(address from, address to, uint160 amount, address token) external;\\n\\n /// @notice Transfer approved tokens in a batch\\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\\n /// @dev Requires the from addresses to have approved at least the desired amount\\n /// of tokens to msg.sender.\\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\\n\\n /// @notice Enables performing a \\\"lockdown\\\" of the sender's Permit2 identity\\n /// by batch revoking approvals\\n /// @param approvals Array of approvals to revoke.\\n function lockdown(TokenSpenderPair[] calldata approvals) external;\\n\\n /// @notice Invalidate nonces for a given (token, spender) pair\\n /// @param token The token to invalidate nonces for\\n /// @param spender The spender to invalidate nonces for\\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\\n}\\n\",\"keccak256\":\"0xbfddf3c6b671cc3c00dd342a9ee23612e0524103cf827a4cfd89c1ae0dc0309f\",\"license\":\"MIT\"},\"contracts/interfaces/external/ICurvePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n// Kind 1\\n// Example v0.2.4 tripool (stables)\\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\\ninterface ICurvePoolKind1 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n\\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\\n}\\n\\n// Kind 2\\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\\ninterface ICurvePoolKind2 {\\n function coins(uint256 index) external view returns (address);\\n\\n function base_coins(uint256 index) external view returns (address);\\n\\n // 0x3df02124\\n function exchange(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n int128 i,\\n int128 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\\n// Kind 3\\n// Example v0.3.0, \\\"# EUR/3crv pool where 3crv is _second_, not first\\\"\\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\\n// NOTE: This contract has an `exchange_underlying` with a receiver also\\ninterface ICurvePoolKind3 {\\n function coins(uint256 index) external view returns (address);\\n\\n function underlying_coins(uint256 index) external view returns (address);\\n\\n function exchange(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n\\n function exchange_underlying(\\n uint256 i,\\n uint256 j,\\n uint256 dx,\\n uint256 min_dy\\n ) external payable returns (uint256);\\n}\\n\",\"keccak256\":\"0x65df78857e648d83cad3edf7e5c2bf4c77be2e58916c6c404e45677f0971ec42\",\"license\":\"MIT\"},\"contracts/interfaces/external/IEIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\ninterface IEIP712 {\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xb8fcd9ab837508adefbc619330151c4dc234a6738cdd08f4e108bfcc1908e5d8\",\"license\":\"MIT\"},\"contracts/interfaces/external/IPermit2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\\n\\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\\n}\\n\",\"keccak256\":\"0x9ea8e6c589429d5edeb0c9bd091b3883536e36d947653fa7cc432bd3bcab2367\",\"license\":\"MIT\"},\"contracts/interfaces/external/ISignatureTransfer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {IEIP712} from './IEIP712.sol';\\n\\n/// @title SignatureTransfer\\n/// @notice Handles ERC20 token transfers through signature based actions\\n/// @dev Requires user's token approval on the Permit2 contract\\ninterface ISignatureTransfer is IEIP712 {\\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\\n /// @param maxAmount The maximum amount a spender can request to transfer\\n error InvalidAmount(uint256 maxAmount);\\n\\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\\n error LengthMismatch();\\n\\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\\n\\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\\n struct TokenPermissions {\\n // ERC20 token address\\n address token;\\n // the maximum amount that can be spent\\n uint256 amount;\\n }\\n\\n /// @notice The signed permit message for a single token transfer\\n struct PermitTransferFrom {\\n TokenPermissions permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice Specifies the recipient address and amount for batched transfers.\\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\\n struct SignatureTransferDetails {\\n // recipient address\\n address to;\\n // spender requested amount\\n uint256 requestedAmount;\\n }\\n\\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\\n /// @dev Note that a user still signs over a spender address\\n struct PermitBatchTransferFrom {\\n // the tokens and corresponding amounts permitted for a transfer\\n TokenPermissions[] permitted;\\n // a unique value for every token owner's signature to prevent signature replays\\n uint256 nonce;\\n // deadline on the permit signature\\n uint256 deadline;\\n }\\n\\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\\n /// @dev It returns a uint256 bitmap\\n /// @dev The index, or wordPosition is capped at type(uint248).max\\n function nonceBitmap(address, uint256) external view returns (uint256);\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers a token using a signed permit message\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails The spender's requested transfer details for the permitted token\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitTransferFrom memory permit,\\n SignatureTransferDetails calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param signature The signature to verify\\n function permitTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Transfers multiple tokens using a signed permit message\\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\\n /// @notice Includes extra data provided by the caller to verify signature over\\n /// @param permit The permit data signed over by the owner\\n /// @param owner The owner of the tokens to transfer\\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\\n /// @param witness Extra data to include when checking the user signature\\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\\n /// @param signature The signature to verify\\n function permitWitnessTransferFrom(\\n PermitBatchTransferFrom memory permit,\\n SignatureTransferDetails[] calldata transferDetails,\\n address owner,\\n bytes32 witness,\\n string calldata witnessTypeString,\\n bytes calldata signature\\n ) external;\\n\\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\\n /// @dev The wordPos is maxed at type(uint248).max\\n /// @param wordPos A number to index the nonceBitmap at\\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\\n}\\n\",\"keccak256\":\"0x6e8fc386e63b612a87ebb33c836457702127fc7b86e9498f2a6dc7dd36f5c6b3\",\"license\":\"MIT\"},\"contracts/interfaces/external/IStargateRouter.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity >=0.7.6;\\npragma abicoder v2;\\n\\ninterface IStargateRouter {\\n struct lzTxObj {\\n uint256 dstGasForCall;\\n uint256 dstNativeAmount;\\n bytes dstNativeAddr;\\n }\\n\\n function swap(\\n uint16 _dstChainId,\\n uint256 _srcPoolId,\\n uint256 _dstPoolId,\\n address payable _refundAddress,\\n uint256 _amountLD,\\n uint256 _minAmountLD,\\n lzTxObj memory _lzTxParams,\\n bytes calldata _to,\\n bytes calldata _payload\\n ) external payable;\\n}\\n\",\"keccak256\":\"0xfeaae75a5900328c68a630720e29a7c613ab3e628d93cbf432abd660083a29bf\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/external/IUniswapV2Pair.sol\":{\"content\":\"pragma solidity >=0.5.0;\\n\\ninterface IUniswapV2Pair {\\n function getReserves()\\n external\\n view\\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x9db3539ee014c7b82d3ef721a09c89efe134d0441b01df60dd61ef78afd8658e\"},\"contracts/interfaces/external/IUniswapV3Pool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IUniswapV3Pool {\\n function swap(\\n address recipient,\\n bool zeroForOne,\\n int256 amountSpecified,\\n uint160 sqrtPriceLimitX96,\\n bytes calldata data\\n ) external returns (int256 amount0, int256 amount1);\\n\\n function token0() external view returns (address);\\n\\n function token1() external view returns (address);\\n\\n function liquidity() external view returns (uint128);\\n}\\n\",\"keccak256\":\"0xeb847b1091ccd93b6f7bd93622fec71a424740bc5820a1ef0abbcb07e0f70cc9\",\"license\":\"MIT\"},\"contracts/libraries/LibCurve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\\n\\nlibrary LibCurve {\\n error UnhandledPoolKind();\\n\\n function exchange(\\n uint8 kind,\\n bool underlying,\\n address pool,\\n uint256 eth,\\n uint8 i,\\n uint8 j,\\n uint256 dx,\\n uint256 min_dy\\n ) internal {\\n if (kind == 1) {\\n if (underlying) {\\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind1(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 2) {\\n if (underlying) {\\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n } else {\\n ICurvePoolKind2(pool).exchange{value: eth}(\\n int128(uint128(i)),\\n int128(uint128(j)),\\n dx,\\n min_dy\\n );\\n }\\n } else if (kind == 3) {\\n if (underlying) {\\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n } else {\\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\\n }\\n } else {\\n revert UnhandledPoolKind();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4fe4a09d7809f1bb73bd5bbb54597788ab863526408134ee24622534e6cba00\",\"license\":\"MIT\"},\"contracts/libraries/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\\n/******************************************************************************/\\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\\n\\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\\n// The loupe functions are required by the EIP2535 Diamonds standard\\n\\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\\n\\nlibrary LibDiamond {\\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(\\n _diamondCut[facetIndex].facetAddress,\\n _diamondCut[facetIndex].functionSelectors\\n );\\n } else {\\n revert('LibDiamondCut: Incorrect FacetCutAction');\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress == address(0),\\n \\\"LibDiamondCut: Can't add function that already exists\\\"\\n );\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\\n );\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(\\n oldFacetAddress != _facetAddress,\\n \\\"LibDiamondCut: Can't replace function with same function\\\"\\n );\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds\\n .facetFunctionSelectors[_facetAddress]\\n .functionSelectors\\n .length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\\n lastSelectorPosition\\n ];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\\n selectorPosition\\n );\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n return;\\n }\\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up error\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(error)\\n revert(add(32, error), returndata_size)\\n }\\n } else {\\n revert InitializationFunctionReverted(_init, _calldata);\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x341f5cbd88d747bcd5beb54a939ddfb8111d04b7a28b1071a4f2a8e4fcfdd216\",\"license\":\"MIT\"},\"contracts/libraries/LibKitty.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport {LibDiamond} from './LibDiamond.sol';\\n\\nlibrary LibKitty {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n /**\\n * The swap fee is over the maximum allowed\\n */\\n error FeeTooHigh(uint16 maxFeeBps);\\n\\n event CollectedFee(\\n address indexed partner,\\n address indexed token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n );\\n\\n struct State {\\n /**\\n * Set of partner balances. An address is added when the partner is first credited\\n */\\n EnumerableSet.AddressSet partners;\\n /**\\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\\n * Tokens are not removed from this set when a partner withdraws.\\n * Mapping: Partner -> token set\\n */\\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\\n /**\\n * Token balances per partner\\n * Mapping: Partner -> token -> balance\\n */\\n mapping(address => mapping(address => uint256)) partnerBalances;\\n /**\\n * Total balances per token for all partners.\\n * Mapping: token -> balance\\n */\\n mapping(address => uint256) partnerBalancesTotal;\\n }\\n\\n uint16 private constant MAX_FEE_BPS = 2_000;\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\\n\\n assembly {\\n s.slot := storagePosition\\n }\\n }\\n\\n /**\\n * By using a library function we ensure that the storage used by the library is whichever contract\\n * is calling this function\\n */\\n function registerCollectedFee(\\n address partner,\\n address token,\\n uint256 partnerFee,\\n uint256 diamondFee\\n ) internal {\\n State storage s = state();\\n\\n if (token != address(0)) {\\n s.partnerTokens[partner].add(token);\\n }\\n\\n s.partners.add(partner);\\n\\n unchecked {\\n s.partnerBalances[partner][token] += partnerFee;\\n s.partnerBalancesTotal[token] += partnerFee;\\n }\\n\\n emit CollectedFee(partner, token, partnerFee, diamondFee);\\n }\\n\\n function calculateAndRegisterFee(\\n address partner,\\n address token,\\n uint16 feeBps,\\n uint256 amountOutQuoted,\\n uint256 amountOutActual\\n ) internal returns (uint256 amountOutUser_) {\\n if (feeBps > MAX_FEE_BPS) {\\n revert FeeTooHigh(MAX_FEE_BPS);\\n }\\n\\n unchecked {\\n uint256 feeTotal;\\n uint256 feeBasis = amountOutActual;\\n\\n if (amountOutActual > amountOutQuoted) {\\n // Positive slippage\\n feeTotal = amountOutActual - amountOutQuoted;\\n\\n // Change the fee basis for use below\\n feeBasis = amountOutQuoted;\\n }\\n\\n // Fee taken from actual\\n feeTotal += (feeBasis * feeBps) / 10_000;\\n\\n // If a partner is set, split the fee in half\\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\\n uint256 feeDiamond = feeTotal - feePartner;\\n\\n if (feeDiamond > 0) {\\n registerCollectedFee(partner, token, feePartner, feeDiamond);\\n }\\n\\n return amountOutActual - feeTotal;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbfbb3d7dccab530c9a30835fd836bfceeff64fadbdd39818a216f59fce1b371f\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV2Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\\n\\nlibrary LibUniV2Like {\\n function getAmountsOut(\\n uint16[] memory poolFeesBps,\\n uint256 amountIn,\\n address[] memory tokens,\\n address[] memory pools\\n ) internal view returns (uint256[] memory amounts) {\\n uint256 poolLength = pools.length;\\n\\n amounts = new uint256[](tokens.length);\\n amounts[0] = amountIn;\\n\\n for (uint256 index; index < poolLength; ) {\\n address token0 = tokens[index];\\n address token1 = tokens[index + 1];\\n\\n // For 30 bps, multiply by 9970\\n uint256 feeFactor = 10_000 - poolFeesBps[index];\\n\\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\\n\\n if (token0 > token1) {\\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\\n }\\n\\n unchecked {\\n amountIn =\\n ((amountIn * feeFactor) * reserveOut) /\\n ((reserveIn * 10_000) + (amountIn * feeFactor));\\n }\\n\\n // Recycling `amountIn`\\n amounts[index + 1] = amountIn;\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0448481d2a71459b54795c8fc2b9672898f66acbf24d9a15b4ca256622fb2bca\",\"license\":\"MIT\"},\"contracts/libraries/LibUniV3Like.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nlibrary LibUniV3Like {\\n error CallbackAlreadyActive();\\n error CallbackStillActive();\\n\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\\n\\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\\n\\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\\n\\n struct CallbackState {\\n uint256 amount;\\n address payer;\\n address token;\\n }\\n\\n struct State {\\n // TODO: Does this help by using `MSTORE8`?\\n uint8 isActive;\\n /**\\n * Transient storage variable used in the callback\\n */\\n CallbackState callback;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function beforeCallback(CallbackState memory callback) internal {\\n if (state().isActive == 1) {\\n revert CallbackAlreadyActive();\\n }\\n\\n state().isActive = 1;\\n state().callback = callback;\\n }\\n\\n function afterCallback() internal view {\\n if (state().isActive == 1) {\\n // The field is expected to be zeroed out by the callback\\n revert CallbackStillActive();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe18789d0c695d057cefb7343bf45f0e113e91f207b18dfe49119a85f56f0792c\",\"license\":\"MIT\"},\"contracts/libraries/LibWarp.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\\n\\nlibrary LibWarp {\\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\\n\\n struct State {\\n IWETH weth;\\n IPermit2 permit2;\\n IStargateRouter stargateRouter;\\n }\\n\\n function state() internal pure returns (State storage s) {\\n bytes32 slot = DIAMOND_STORAGE_SLOT;\\n\\n assembly {\\n s.slot := slot\\n }\\n }\\n\\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\\n return (amount * (10_000 - slippage)) / 10_000;\\n }\\n}\\n\",\"keccak256\":\"0xfaa8a495f0b79d655d2cda94fc6f157d1177972b2f39ecd7f95fe5ca15c3c9c4\",\"license\":\"MIT\"},\"contracts/libraries/PermitParams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nstruct PermitParams {\\n uint256 nonce;\\n bytes signature;\\n}\\n\",\"keccak256\":\"0x71ad794ae61c4443974102a0b88f4e43deb6fcb1e57c04e08c44f903bac7e1fc\",\"license\":\"MIT\"},\"contracts/libraries/Stream.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\n/**\\n * Stream reader\\n *\\n * Note that the stream position is always behind by one as per the\\n * original implementation\\n *\\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\\n */\\nlibrary Stream {\\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\\n assembly {\\n // Get a pointer to the next free memory\\n stream := mload(0x40)\\n\\n // Move the free memory pointer forward by 64 bytes, since\\n // this function will store 2 words (64 bytes) to memory.\\n mstore(0x40, add(stream, 64))\\n\\n // Store a pointer to the data in the first word of the stream\\n mstore(stream, data)\\n\\n // Store a pointer to the end of the data in the second word of the stream\\n let length := mload(data)\\n mstore(add(stream, 32), add(data, length))\\n }\\n }\\n\\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\\n uint256 pos;\\n uint256 finish;\\n assembly {\\n pos := mload(stream)\\n finish := mload(add(stream, 32))\\n }\\n return pos < finish;\\n }\\n\\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 1)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 2)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 3)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 4)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 6)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 32)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readAddress(uint256 stream) internal pure returns (address res) {\\n assembly {\\n let pos := mload(stream)\\n pos := add(pos, 20)\\n res := mload(pos)\\n mstore(stream, pos)\\n }\\n }\\n\\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\\n assembly {\\n let pos := mload(stream)\\n res := add(pos, 32)\\n let length := mload(res)\\n mstore(stream, add(res, length))\\n }\\n }\\n\\n function readAddresses(\\n uint256 stream,\\n uint256 count\\n ) internal pure returns (address[] memory res) {\\n res = new address[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readAddress(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n\\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\\n res = new uint16[](count);\\n\\n for (uint256 index; index < count; ) {\\n res[index] = readUint16(stream);\\n\\n unchecked {\\n index++;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x1c4eccca88e3487c6b6663ce51b77ea778e91b801373223e998fe96e2fff1750\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50614669806100206000396000f3fe60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c8063dc7b39db14610023575b600080fd5b61003661003136600461403f565b610038565b005b81610100015165ffffffffffff1642111561007f576040517f1ab7da6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161016081018252600080825260208083018281529383018281526060808501848152608080870186905260a0870186815260c080890188905260e0808a01898152610100808c018b81526101208d018c90526101408d019b909b528e5173ffffffffffffffffffffffffffffffffffffffff9081168d52998f015161ffff16909c52958d01518816909652948b0151909252928901519052908701805183169091529386015165ffffffffffff16909152915190911661019b578260c0015134101561017b576040517f1985c73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015161018a9034614191565b6101408201523060c0820152610316565b3360c0820152346101408201527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e1060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632b67b5703360405180606001604052806040518060800160405280896080015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015173ffffffffffffffffffffffffffffffffffffffff16815260200189610100015165ffffffffffff168152602001886000013565ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff16815260200187610100015165ffffffffffff168152508580602001906102c491906141a4565b6040518563ffffffff1660e01b81526004016102e39493929190614210565b600060405180830381600087803b1580156102fd57600080fd5b505af1158015610311573d6000803e3d6000fd5b505050505b600061033b846101200151604080518082019091528181528151909101602082015290565b90506103478183610502565b60a08082015160e0830151918701519294509173ffffffffffffffffffffffffffffffffffffffff8083169116146103ab576040517fae39073000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103bd8660e0015187604001516106cf565b8210156103f6576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101408401511561043457610140840151604051339180156108fc02916000818181858888f19350505050158015610432573d6000803e3d6000fd5b505b83610120015160010361044957505050505050565b61046686600001518760a0015188602001518960e00151866106fd565b915073ffffffffffffffffffffffffffffffffffffffff81166104d357856060015173ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501580156104cd573d6000803e3d6000fd5b506104fa565b60608601516104fa9073ffffffffffffffffffffffffffffffffffffffff831690846107be565b505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152600061056d8480516001018051915290565b60ff16905060005b818110156106c357600061058f8680516001018051915290565b60ff169050600181036105ac576105a585610897565b94506106b0565b600281036105bd576105a585610a4c565b600381036105cf576105a58686610c95565b600481036105e1576105a58686611255565b600581036105f3576105a586866115b2565b60068103610605576105a58686611d44565b60078103610617576105a58686612256565b60088103610629576105a5868661277d565b6009810361067e5761063c600184614191565b8214610674576040517fe31c95e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105a58686612b8e565b6040517f8ccd166700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50806106bb816142d2565b915050610575565b50829150505b92915050565b60006127106106de838261430a565b6106ec9061ffff1685614325565b6106f6919061436b565b9392505050565b60006107d061ffff85161115610748576040517f8ea70c070000000000000000000000000000000000000000000000000000000081526107d060048201526024015b60405180910390fd5b6000828481111561075a575050828203835b61271061ffff87168202049190910190600073ffffffffffffffffffffffffffffffffffffffff8916156107945760646032840204610797565b60005b90508083038382146107af576107af8a8a8484612fc9565b50505090910395945050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526108929084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526130ce565b505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e080820183905261010082018390526101208201839052610140820192909252908201517f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e109073ffffffffffffffffffffffffffffffffffffffff1615610964576040517f45369fbb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff1630146109b7576040517f32d40df100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805473ffffffffffffffffffffffffffffffffffffffff1660e0840181905260a0840151604080517fd0e30db0000000000000000000000000000000000000000000000000000000008152905163d0e30db0929160048082019260009290919082900301818588803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b50959695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052907f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e10805460e085015191925073ffffffffffffffffffffffffffffffffffffffff918216911614610b21576040517fb2ee070800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c083015173ffffffffffffffffffffffffffffffffffffffff81163014801590610b4d573060c08601525b600060e08601528015610bfe57600183015460a086015184546040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152306024830152928316604482015290821660648201529116906336c7851690608401600060405180830381600087803b158015610be557600080fd5b505af1158015610bf9573d6000803e3d6000fd5b505050505b825460a08601516040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691632e1a7d4d91610c5a9160040190815260200190565b600060405180830381600087803b158015610c7457600080fd5b505af1158015610c88573d6000803e3d6000fd5b5096979650505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16610d3f576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660011460408201528351600201805190855261ffff16606082015260c08301513073ffffffffffffffffffffffffffffffffffffffff90911603610e3157610e2c81602001518460a001518560e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b610f09565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c0840151602083015160a086015160e08701516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff948516600482015292841660248401529083166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50503060c086015250505b600080826020015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f91906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508260400151610faf57905b606083015160a086015161ffff6127109283031691840290820290810190830281610fdc57610fdc61433c565b0460a08701525082516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611051573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110759190614414565b9050836020015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f85604001516110aa578760a001516110ad565b60005b86604001516110bd5760006110c3565b8860a001515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092526024820152306044820152608060648201526000608482015260a401600060405180830381600087803b15801561112d57600080fd5b505af1158015611141573d6000803e3d6000fd5b505085516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000935073ffffffffffffffffffffffffffffffffffffffff90911691506370a0823190602401602060405180830381865afa1580156111b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d99190614414565b9050818110806111f6575060a08701516111f3908361442d565b81105b1561122d576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050915173ffffffffffffffffffffffffffffffffffffffff1660e085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260006112c08480516001018051915290565b60ff16905060008360a0015190506000600283101561130b576040517f1d6beb5700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060005b85811015611580576000611326600188614191565b82106113325785611362565b6127106113458b80516002018051915290565b61ffff168a60a001516113589190614325565b611362919061436b565b90508581111561139e576040517f0f24c51700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113a88187614191565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260c080820183815260e08084018581526101008501869052610120850186905261014085019590955260a08401879052918e015173ffffffffffffffffffffffffffffffffffffffff908116909152908d0151169091529096506114378b82610502565b9050806101200151600103611478576040517fd35869f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611493578060c0015193508060e001519450611565565b8473ffffffffffffffffffffffffffffffffffffffff168160e0015173ffffffffffffffffffffffffffffffffffffffff16146114fc576040517fd7af48f200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168160c0015173ffffffffffffffffffffffffffffffffffffffff1614611565576040517f51a769fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a0810151611574908761442d565b95505050600101611311565b5073ffffffffffffffffffffffffffffffffffffffff90811660c08801521660e086015260a085015250919392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915261162f60405180606001604052806060815260200160608152602001606081525090565b60006116418580516001018051915290565b60ff16905061165181600161442d565b67ffffffffffffffff81111561166957611669613ed2565b604051908082528060200260200182016040528015611692578160200160208202803683370190505b5080835260e085015181519091906000906116af576116af614440565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060005b818110156117485785516014018051908752835161170b83600161442d565b8151811061171b5761171b614440565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016116ec565b5061175385826131dd565b6020830152611762858261327f565b604083015281518051600091908390811061177f5761177f614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118199190614414565b9050600061183984604001518760a0015186600001518760200151613308565b90503073ffffffffffffffffffffffffffffffffffffffff168660c0015173ffffffffffffffffffffffffffffffffffffffff16036118c8576118c3846020015160008151811061188c5761188c614440565b60200260200101518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166107be9092919063ffffffff16565b6119c3565b7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e115460c08701516020860151805173ffffffffffffffffffffffffffffffffffffffff909316926336c7851692919060009061192657611926614440565b60200260200101518960a001518a60e001516040518563ffffffff1660e01b815260040161198a949392919073ffffffffffffffffffffffffffffffffffffffff948516815292841660208401529083166040830152909116606082015260800190565b600060405180830381600087803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b50503060c089015250505b60005b83811015611bc75760006119db82600161442d565b90506000866000015182815181106119f5576119f5614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600001518481518110611a2957611a29614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610611a53576000611a56565b60015b905060006002886000015151611a6c9190614191565b8410611a785730611a97565b87602001518381518110611a8e57611a8e614440565b60200260200101515b905087602001518481518110611aaf57611aaf614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663022c0d9f83611af657868581518110611ae957611ae9614440565b6020026020010151611af9565b60005b84611b05576000611b20565b878681518110611b1757611b17614440565b60200260200101515b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252602482015273ffffffffffffffffffffffffffffffffffffffff84166044820152608060648201526000608482015260a401600060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b5050600190950194506119c69350505050565b50600084600001518481518110611be057611be0614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a9190614414565b90508160018351611c8b9190614191565b81518110611c9b57611c9b614440565b60200260200101518760a001818152505082811080611cc7575060a0870151611cc4908461442d565b81105b15611cfe576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451805185908110611d1257611d12614440565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff1660e088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160808101825260008082526020820181905291810182905260608101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff908116602083015260e084015116611e46576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed89190614414565b90506000826000015173ffffffffffffffffffffffffffffffffffffffff168560e0015173ffffffffffffffffffffffffffffffffffffffff16109050611f7060405180606001604052808760a0015181526020018760c0015173ffffffffffffffffffffffffffffffffffffffff1681526020018760e0015173ffffffffffffffffffffffffffffffffffffffff1681525061353d565b801561205457602083015160a0868101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203c919061446f565b9150508061204990614493565b60a08701525061213c565b602083015160a0868101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529173ffffffffffffffffffffffffffffffffffffffff169063128acb089060c40160408051808303816000875af1158015612105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612129919061446f565b50905061213581614493565b60a0870152505b6121446136a6565b82516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190614414565b9050828110806121f3575060a08601516121f0908461442d565b81105b1561222a576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050905173ffffffffffffffffffffffffffffffffffffffff1660e084015250503060c0820152919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526122d360405180606001604052806060815260200160608152602001606081525090565b60006122e58580516001018051915290565b60ff1690506122f485826131dd565b825261230085826131dd565b60208301528151600090612315600184614191565b8151811061232557612325614440565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c49190614414565b905060005b8381101561268757600081156124035785516123e6600184614191565b815181106123f6576123f6614440565b6020026020010151612409565b8760e001515b90508560000151828151811061242157612421614440565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811660e08b018190526040805160608101825260a08d0151815260c08d0151841694810194909452918416918301829052119061247f9061353d565b8260000361248e573060c08a01525b6000876020015184815181106124a6576124a6614440565b6020026020010151905081156125905760a08a8101516040517f128acb08000000000000000000000000000000000000000000000000000000008152306004820152841515602482015260448101919091526401000276a460648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af1158015612554573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612578919061446f565b9150508061258590614493565b60a08c015250612674565b60a08a8101516040517f128acb080000000000000000000000000000000000000000000000000000000081523060048201528415156024820152604481019190915273fffd8963efd1fc6a506488495d951d5263988d2560648201526084810191909152600060a482018190529073ffffffffffffffffffffffffffffffffffffffff83169063128acb089060c40160408051808303816000875af115801561263d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612661919061446f565b50905061266d81614493565b60a08c0152505b61267c6136a6565b5050506001016123c9565b5060e08601516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d9190614414565b90508181108061273a575060a0870151612737908361442d565b81105b15612771576040517f946beb5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1681528351601401805190855273ffffffffffffffffffffffffffffffffffffffff1660208201528351600101805190855260ff1660408201528351600101805190855260ff1660608201528351600101805190855260ff1660808201528351600101805190855260ff1660011460a082015260e0830151815160c085015173ffffffffffffffffffffffffffffffffffffffff928316159291821615913091161461299e577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c086015160a087015160e08801516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b15801561297f57600080fd5b505af1158015612993573d6000803e3d6000fd5b50503060c088015250505b600081612a3b5783516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a369190614414565b612a3d565b475b905082612a7b57612a7b84602001518760a001518860e0015173ffffffffffffffffffffffffffffffffffffffff166137069092919063ffffffff16565b612ab584608001518560a00151866020015186612a99576000612a9f565b8960a001515b886040015189606001518c60a0015160006137fc565b600082612b525784516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d9190614414565b612b54565b475b855173ffffffffffffffffffffffffffffffffffffffff1660e08901529050612b7d8282614191565b60a088015250949695505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260e082015173ffffffffffffffffffffffffffffffffffffffff16612c38576040517fb10b947e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c606040518060600160405280600061ffff16815260200160008152602001600081525090565b8351600201805190855261ffff1681528351600101805190855260ff1660208201528351600101805190855260ff166040820152825160e0840151602085015160a0860151612cb293929190806106fd565b60a084015260608301516080840151612ccb91906106cf565b8360a001511015612d08576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff1615612e6c5760c083015173ffffffffffffffffffffffffffffffffffffffff163014612e1a577f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106001015460c084015160a085015160e08601516040517f36c7851600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201523060248201529183166044830152821660648201529116906336c7851690608401600060405180830381600087803b158015612dfb57600080fd5b505af1158015612e0f573d6000803e3d6000fd5b50503060c086015250505b612e6c7f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e106002015460a085015160e086015173ffffffffffffffffffffffffffffffffffffffff908116921690613706565b60016101208401527f1c1cf3c8827d48db80e17913589584c81d7f8da7f2100c9a87a7bf64829a0e125461014084015182516020840151604085015160a088015173ffffffffffffffffffffffffffffffffffffffff90951694639fbf10fc949392919030906064612edf82605f614325565b612ee9919061436b565b60405180606001604052806000815260200160008152602001604051806020016040528060008152508152508c60400151604051602001612f55919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526040518a63ffffffff1660e01b8152600401612f87989796959493929190614539565b6000604051808303818588803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506000610140870152509395945050505050565b7f4edbd34b5b006870ab724677d99b508debf8dcac0dc8134c9c43b93f8afe50f073ffffffffffffffffffffffffffffffffffffffff8416156130395773ffffffffffffffffffffffffffffffffffffffff8516600090815260028201602052604090206130379085613b91565b505b6130438186613b91565b5073ffffffffffffffffffffffffffffffffffffffff858116600081815260038401602090815260408083209489168084529482528083208054890190556004860182529182902080548801905581518781529081018690527fb9c71741297b7329823b5575aa676062720448277d6da61cf68eb0fed6c4baf4910160405180910390a35050505050565b6000613130826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613bb39092919063ffffffff16565b905080516000148061315157508080602001905181019061315191906145e2565b610892576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161073f565b60608167ffffffffffffffff8111156131f8576131f8613ed2565b604051908082528060200260200182016040528015613221578160200160208202803683370190505b50905060005b82811015613278578351601401805190855282828151811061324b5761324b614440565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101613227565b5092915050565b60608167ffffffffffffffff81111561329a5761329a613ed2565b6040519080825280602002602001820160405280156132c3578160200160208202803683370190505b50905060005b8281101561327857835160020180519085528282815181106132ed576132ed614440565b61ffff909216602092830291909101909101526001016132c9565b805182516060919067ffffffffffffffff81111561332857613328613ed2565b604051908082528060200260200182016040528015613351578160200160208202803683370190505b509150848260008151811061336857613368614440565b60200260200101818152505060005b8181101561353357600085828151811061339357613393614440565b602002602001015190506000868360016133ad919061442d565b815181106133bd576133bd614440565b6020026020010151905060008984815181106133db576133db614440565b60200260200101516127106133f0919061430a565b61ffff16905060008088868151811061340b5761340b614440565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561345d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348191906143c4565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1611156134dc57905b828b0282612710020181848d0202816134f7576134f761433c565b049a508a8861350788600161442d565b8151811061351757613517614440565b6020908102919091010152505060019093019250613377915050565b5050949350505050565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff1660010361359b576040517f65d4e04900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a805460017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090911617905580517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7b5560208101517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7c80547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff938416179091556040909201517f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7d80549093169116179055565b7f3029b773e586da235d6a0709bacd2cb14a2e6562f997f3c8684513a487bcbf7a5460ff16600103613704576040517f129c8cdb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790526137928482613bca565b6137f65760405173ffffffffffffffffffffffffffffffffffffffff84166024820152600060448201526137ec9085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610810565b6137f684826130ce565b50505050565b8760ff1660010361392a5786156138b5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b6000604051808303818588803b15801561389757600080fd5b505af11580156138ab573d6000803e3d6000fd5b5050505050613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df0212490879060840161387e565b8760ff16600203613a6a5786156139f5576040517fa6417ed600000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff87169063a6417ed69087906084015b60206040518083038185885af11580156139ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906139ef9190614414565b50613b87565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260ff808616600f90810b6004840152908516900b6024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690633df021249087906084016139ac565b8760ff16600303613b55578615613ae8576040517f65b2489b00000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff8716906365b2489b9087906084016139ac565b6040517f5b41b90800000000000000000000000000000000000000000000000000000000815260ff808616600483015284166024820152604481018390526064810182905273ffffffffffffffffffffffffffffffffffffffff871690635b41b9089087906084016139ac565b6040517ff1c43ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60006106f68373ffffffffffffffffffffffffffffffffffffffff8416613c8b565b6060613bc28484600085613cda565b949350505050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1684604051613bf49190614604565b6000604051808303816000865af19150503d8060008114613c31576040519150601f19603f3d011682016040523d82523d6000602084013e613c36565b606091505b5091509150818015613c60575080511580613c60575080806020019051810190613c6091906145e2565b8015613c82575073ffffffffffffffffffffffffffffffffffffffff85163b15155b95945050505050565b6000818152600183016020526040812054613cd2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106c9565b5060006106c9565b606082471015613d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161073f565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d959190614604565b60006040518083038185875af1925050503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b5091509150613de887838387613df3565b979650505050505050565b60608315613e89578251600003613e825773ffffffffffffffffffffffffffffffffffffffff85163b613e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161073f565b5081613bc2565b613bc28383815115613e9e5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f9190614620565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715613f2557613f25613ed2565b60405290565b803573ffffffffffffffffffffffffffffffffffffffff81168114613f4f57600080fd5b919050565b803561ffff81168114613f4f57600080fd5b803565ffffffffffff81168114613f4f57600080fd5b600082601f830112613f8d57600080fd5b813567ffffffffffffffff80821115613fa857613fa8613ed2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613fee57613fee613ed2565b8160405283815286602085880101111561400757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006040828403121561403957600080fd5b50919050565b6000806040838503121561405257600080fd5b823567ffffffffffffffff8082111561406a57600080fd5b90840190610140828703121561407f57600080fd5b614087613f01565b61409083613f2b565b815261409e60208401613f54565b60208201526140af60408401613f54565b60408201526140c060608401613f2b565b60608201526140d160808401613f2b565b60808201526140e260a08401613f2b565b60a082015260c083013560c082015260e083013560e0820152610100614109818501613f66565b90820152610120838101358381111561412157600080fd5b61412d89828701613f7c565b82840152505080945050602085013591508082111561414b57600080fd5b5061415885828601614027565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c9576106c9614162565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141d957600080fd5b83018035915067ffffffffffffffff8211156141f457600080fd5b60200191503681900382131561420957600080fd5b9250929050565b600061010073ffffffffffffffffffffffffffffffffffffffff80881684528651818151166020860152816020820151166040860152604081015165ffffffffffff80821660608801528060608401511660808801525050508060208801511660a085015250604086015160c08401528060e08401528381840152506101208385828501376000838501820152601f9093017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101909101949350505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361430357614303614162565b5060010190565b61ffff82811682821603908082111561327857613278614162565b80820281158282048414176106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80516dffffffffffffffffffffffffffff81168114613f4f57600080fd5b6000806000606084860312156143d957600080fd5b6143e2846143a6565b92506143f0602085016143a6565b9150604084015163ffffffff8116811461440957600080fd5b809150509250925092565b60006020828403121561442657600080fd5b5051919050565b808201808211156106c9576106c9614162565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561448257600080fd5b505080516020909101519092909150565b60007f800000000000000000000000000000000000000000000000000000000000000082036144c4576144c4614162565b5060000390565b60005b838110156144e65781810151838201526020016144ce565b50506000910152565b600081518084526145078160208601602086016144cb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600061012061ffff8b16835289602084015288604084015273ffffffffffffffffffffffffffffffffffffffff881660608401528660808401528560a08401528060c0840152845181840152506020840151610140830152604084015160606101608401526145ac6101808401826144ef565b905082810360e08401526145c081856144ef565b838103610100850152600081529050602081019b9a5050505050505050505050565b6000602082840312156145f457600080fd5b815180151581146106f657600080fd5b600082516146168184602087016144cb565b9190910192915050565b6020815260006106f660208301846144ef56fea26469706673582212207984511f782cf083daed8a29b308c3ee2151db78fe3c841e6f30cde50199616064736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/hardhat/deployments/polygon/solcInputs/025166ddb0f771753ceec554ac05c5f7.json b/packages/hardhat/deployments/polygon/solcInputs/025166ddb0f771753ceec554ac05c5f7.json new file mode 100644 index 00000000..d03365ab --- /dev/null +++ b/packages/hardhat/deployments/polygon/solcInputs/025166ddb0f771753ceec554ac05c5f7.json @@ -0,0 +1,161 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and the amount will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * This command cannot run inside of a split\n *\n * No more commands should execute after this command since the tokens\n * have all left the chain\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * IStargateRouter.quoteLayerZeroFee\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint256)\n * - dstPoolId (uint256)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n // TODO: Make a new error or rename the existing\n revert EthNotSupportedForWarp();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // The value for `t.token` remains the same and is not chained. It is possible that the user\n // has constructed a command where the srcPoolId is not of the token t.token. This should not\n // be dangerous because only `t.token` is allowed to be transferred\n\n // Collect fees\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: uint16(params.dstChainId),\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // TODO: If the min amount is not met, is the tx reverted or is this refunded?\n _minAmountLD: 0,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encode(uint256(uint160(t.paramRecipient))),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2, address router) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n s.stargateRouter = IStargateRouter(router);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/polygon/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json b/packages/hardhat/deployments/polygon/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json new file mode 100644 index 00000000..d3c23a0d --- /dev/null +++ b/packages/hardhat/deployments/polygon/solcInputs/4bd33b0efaadcd28492d25c3625ab942.json @@ -0,0 +1,191 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "content": "pragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "content": "pragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/Curve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {ICurve} from '../interfaces/ICurve.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * Swaps for Curve pools\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n */\ncontract Curve is ICurve {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (params.tokenIn != address(0)) {\n // TODO: Is this necessary to support USDT? @jflint256: Yes, I think so.\n IERC20(params.tokenIn).forceApprove(params.pool, params.amountIn);\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to address(this)\n LibWarp.state().permit2.transferFrom(\n msg.sender,\n address(this),\n (uint160)(params.amountIn),\n params.tokenIn\n );\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: msg.value,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n // NOTE: `params.amountIn` is not verified to equal `msg.value`\n dx: params.amountIn,\n // NOTE: There is no need to set a min out since the balance is verified\n min_dy: 0\n });\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n amountOut = nextTokenOutBalance - tokenOutBalancePrev;\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/DiamondCutFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\ncontract DiamondCutFacet is IDiamondCut {\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n }\n}\n" + }, + "contracts/facets/DiamondLoupeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';\n\n// The functions in DiamondLoupeFacet MUST be added to a diamond.\n// The EIP-2535 Diamond standard requires these functions.\n\ncontract DiamondLoupeFacet is IDiamondLoupe {\n // Diamond Loupe Functions\n ////////////////////////////////////////////////////////////////////\n /// These functions are expected to be called frequently by tools.\n //\n // struct Facet {\n // address facetAddress;\n // bytes4[] functionSelectors;\n // }\n\n /// @notice Gets all facets and their selectors.\n /// @return facets_ Facet\n function facets() external view override returns (Facet[] memory facets_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n uint256 numFacets = ds.facetAddresses.length;\n facets_ = new Facet[](numFacets);\n for (uint256 i; i < numFacets; i++) {\n address facetAddress_ = ds.facetAddresses[i];\n facets_[i].facetAddress = facetAddress_;\n facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n }\n }\n\n /// @notice Gets all the function selectors provided by a facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view override returns (bytes4[] memory facetFunctionSelectors_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n }\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddresses_ = ds.facetAddresses;\n }\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(\n bytes4 _functionSelector\n ) external view override returns (address facetAddress_) {\n LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n }\n}\n" + }, + "contracts/facets/KittyFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IKitty} from '../interfaces/IKitty.sol';\n\ncontract KittyFacet is IKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n error InsufficientOwnerBalance(uint256 available);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_) {\n LibKitty.State storage s = LibKitty.state();\n\n EnumerableSet.AddressSet storage tokenSet = s.partnerTokens[partner];\n uint256 length = tokenSet.length();\n\n tokens_ = new address[](length);\n\n for (uint256 tokenIndex; tokenIndex < length; tokenIndex++) {\n tokens_[tokenIndex] = tokenSet.at(tokenIndex);\n }\n }\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256) {\n LibKitty.State storage s = LibKitty.state();\n\n return s.partnerBalances[partner][token];\n }\n\n function partnerWithdraw(address token) external {\n LibKitty.State storage s = LibKitty.state();\n\n uint256 balance = s.partnerBalances[msg.sender][token];\n\n if (balance > 0) {\n s.partnerBalances[msg.sender][token] = 0;\n s.partnerBalancesTotal[token] -= balance;\n\n emit PartnerWithdraw(msg.sender, token, balance);\n\n if (token == address(0)) {\n // NOTE: Control transfered to untrusted address\n (bool sent, ) = payable(msg.sender).call{value: balance}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n // NOTE: The token is not removed from the partner's token set\n IERC20(token).safeTransfer(msg.sender, balance);\n }\n }\n }\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external {\n LibDiamond.enforceIsContractOwner();\n\n LibKitty.State storage s = LibKitty.state();\n\n uint256 partnerBalanceTotal = s.partnerBalancesTotal[token];\n\n uint256 balance = token == address(0)\n ? address(this).balance\n : IERC20(token).balanceOf(address(this));\n\n uint256 available = balance - partnerBalanceTotal;\n\n if (amount > available) {\n revert InsufficientOwnerBalance(available);\n }\n\n if (token == address(0)) {\n // Send ETH\n (bool sent, ) = to.call{value: amount}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(token).safeTransfer(to, amount);\n }\n }\n}\n" + }, + "contracts/facets/OwnershipFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {IERC173} from '../interfaces/IERC173.sol';\n\ncontract OwnershipFacet is IERC173 {\n function transferOwnership(address _newOwner) external override {\n LibDiamond.enforceIsContractOwner();\n LibDiamond.setContractOwner(_newOwner);\n }\n\n function owner() external view override returns (address owner_) {\n owner_ = LibDiamond.contractOwner();\n }\n}\n" + }, + "contracts/facets/UniV2LikeFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Like} from '../interfaces/IUniV2Like.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V2 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n *\n * Fees may vary from Uniswap V2's 0.3% (30 bps) and are passed in as `poolFeeBps`.\n *\n * Inspired by https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/RouteProcessor4.sol#L323\n */\ncontract UniV2LikeFacet is IUniV2Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 25 bps, multiply by 9975\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n amountOut =\n ((params.amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (params.amountIn * feeFactor));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(params.pool, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, params.pool, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(params.pool).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n LibWarp.State storage s = LibWarp.state();\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n\n uint256 tokenOutBalancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n params.amountIn,\n params.tokens,\n params.pools\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.tokens[0]).safeTransfer(params.pools[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(\n msg.sender,\n params.pools[0],\n (uint160)(params.amountIn),\n params.tokens[0]\n );\n }\n\n // From https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = isToEth\n ? address(this).balance\n : IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amounts[poolLength]\n );\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV2RouterFacet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IUniV2Router} from '../interfaces/IUniV2Router.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {Errors} from '../libraries/Errors.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ncontract UniV2RouterFacet is IUniV2Router {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n params.tokenIn = address(s.weth);\n }\n\n if (isToEth) {\n params.tokenOut = address(s.weth);\n }\n\n address pair = LibUniV2Router.pairFor(s.uniswapV2Factory, params.tokenIn, params.tokenOut);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pair).getReserves();\n\n if (params.tokenIn > params.tokenOut) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountOut =\n ((params.amountIn * 997) * reserveOut) /\n ((reserveIn * 1000) + (params.amountIn * 997));\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the pool\n IERC20(params.tokenIn).safeTransfer(pair, params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the pool\n s.permit2.transferFrom(msg.sender, pair, (uint160)(params.amountIn), params.tokenIn);\n }\n\n bool zeroForOne = params.tokenIn < params.tokenOut ? true : false;\n\n IUniswapV2Pair(pair).swap(\n zeroForOne ? 0 : amountOut,\n zeroForOne ? amountOut : 0,\n address(this),\n ''\n );\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert Errors.DeadlineExpired();\n }\n\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n uint256 pathLengthMinusOne = params.path.length - 1;\n bool isFromEth = params.path[0] == address(0);\n bool isToEth = params.path[pathLengthMinusOne] == address(0);\n\n if (isFromEth) {\n params.path[0] = address(s.weth);\n }\n\n if (isToEth) {\n params.path[pathLengthMinusOne] = address(s.weth);\n }\n\n (address[] memory pairs, uint256[] memory amounts) = LibUniV2Router.getPairsAndAmountsFromPath(\n s.uniswapV2Factory,\n params.amountIn,\n params.path\n );\n\n // Enforce minimum amount/max slippage\n if (amounts[amounts.length - 1] < LibWarp.applySlippage(params.amountOut, params.slippage)) {\n revert Errors.InsufficientOutputAmount();\n }\n\n if (isFromEth) {\n // From ETH\n if (msg.value != params.amountIn) {\n revert Errors.IncorrectEthValue();\n }\n\n s.weth.deposit{value: msg.value}();\n\n // Transfer tokens to the first pool\n IERC20(params.path[0]).safeTransfer(pairs[0], params.amountIn);\n } else {\n // Permit tokens / set allowance\n s.permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.path[0],\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n\n // Transfer tokens from msg.sender to the first pool\n s.permit2.transferFrom(msg.sender, pairs[0], (uint160)(params.amountIn), params.path[0]);\n }\n\n // https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol\n for (uint index; index < pathLengthMinusOne; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.path[index] < params.path[indexPlusOne] ? true : false;\n address to = index < params.path.length - 2 ? pairs[indexPlusOne] : address(this);\n\n IUniswapV2Pair(pairs[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n ++index;\n }\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.path[pathLengthMinusOne],\n params.feeBps,\n params.amountOut,\n amounts[pathLengthMinusOne]\n );\n\n if (amountOut == 0) {\n revert Errors.ZeroAmountOut();\n }\n\n if (isToEth) {\n // Unwrap WETH\n s.weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert Errors.EthTransferFailed();\n }\n } else {\n IERC20(params.path[pathLengthMinusOne]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/UniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\n/**\n * NOTE: Using a shared internal functions uses about 3K more gas than\n * having two externals with the code duplicated\n */\ncontract UniV3Callback is IUniV3Callback {\n using SafeERC20 for IERC20;\n\n function swapCallback() private {\n if (LibUniV3Like.state().isActive != 1) {\n revert CallbackInactive();\n }\n\n LibUniV3Like.CallbackState memory callback = LibUniV3Like.state().callback;\n\n if (callback.payer == address(this)) {\n IERC20(callback.token).safeTransfer(msg.sender, callback.amount);\n } else {\n LibWarp.state().permit2.transferFrom(\n callback.payer,\n msg.sender,\n (uint160)(callback.amount),\n callback.token\n );\n }\n\n LibUniV3Like.state().isActive = 0;\n }\n\n /**\n * See https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol\n *\n * NOTE: None of these arguments can be trusted\n */\n function uniswapV3SwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n\n /**\n * NOTE: None of these arguments can be trusted\n */\n function algebraSwapCallback(int256, int256, bytes calldata) external {\n swapCallback();\n }\n}\n" + }, + "contracts/facets/UniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {IUniV3Like} from '../interfaces/IUniV3Like.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IUniV3Callback} from './UniV3Callback.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\n/**\n * A router for any Uniswap V3 fork\n *\n * The pools are not trusted to deliver the correct amount of tokens, so the router\n * verifies this.\n *\n * The pool addresses passed in as a parameter instead of being looked up from the factory. The caller\n * may use `getPair` on the factory to calculate pool addresses.\n */\ncontract UniV3Like is IUniV3Like {\n using SafeERC20 for IERC20;\n using Address for address;\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n bool isFromEth = params.tokenIn == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokenIn = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokenOut = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = params.tokenIn < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({\n payer: isFromEth ? address(this) : msg.sender,\n token: params.tokenIn,\n amount: params.amountIn\n })\n );\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n params.deadline\n ),\n permit.signature\n );\n }\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(params.amountIn),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // TODO: This is read twice. Compare gas usage\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut) {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n uint256 poolLength = params.pools.length;\n bool isFromEth = params.tokens[0] == address(0);\n bool isToEth = params.tokens[poolLength] == address(0);\n address payer = isFromEth ? address(this) : msg.sender;\n\n if (isFromEth) {\n IWETH weth = LibWarp.state().weth;\n\n params.tokens[0] = address(weth);\n\n // From ETH\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n weth.deposit{value: msg.value}();\n }\n\n if (isToEth) {\n params.tokens[poolLength] = address(LibWarp.state().weth);\n }\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n amountOut = params.amountIn;\n\n if (!isFromEth) {\n // Permit this contract to move tokens from the sender. The actual transfer happens inside UniV3Callback.\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle(\n IAllowanceTransfer.PermitDetails({\n token: params.tokens[0],\n amount: (uint160)(params.amountIn),\n expiration: params.deadline,\n nonce: (uint48)(permit.nonce)\n }),\n address(this),\n (uint256)(params.deadline)\n ),\n permit.signature\n );\n }\n\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne;\n\n unchecked {\n indexPlusOne = index + 1;\n }\n\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne];\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: payer, token: params.tokens[index], amount: amountOut})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pools[index]).swap(\n address(this),\n zeroForOne,\n int256(amountOut),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n amountOut = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n // TODO: Compare check-and-set with set\n payer = address(this);\n\n index = indexPlusOne;\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n if (\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + amountOut\n ) {\n revert InsufficienTokensDelivered();\n }\n\n // NOTE: Fee is collected as WETH instead of ETH\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokens[poolLength],\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n if (isToEth) {\n // Unwrap WETH\n LibWarp.state().weth.withdraw(amountOut);\n\n (bool sent, ) = params.recipient.call{value: amountOut}('');\n\n if (!sent) {\n revert EthTransferFailed();\n }\n } else {\n IERC20(params.tokens[poolLength]).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct TransientState {\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert EthNotSupportedForWarp();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n if (params.tokenIn != address(0)) {\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n TransientState memory t;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (msg.value == 0) {\n if (params.tokenIn == address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n } else {\n if (params.tokenIn != address(0)) {\n revert UnexpectedValueAndTokenCombination();\n }\n\n if (msg.value != params.amountIn) {\n revert IncorrectEthValue();\n }\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/init/DiamondMultiInit.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// From https://github.com/mudgen/diamond-1-hardhat/blob/main/contracts/upgradeInitializers/DiamondMultiInit.sol\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\n\nerror AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);\n\ncontract DiamondMultiInit {\n // This function is provided in the third parameter of the `diamondCut` function.\n // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.\n\n function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {\n if (_addresses.length != _calldata.length) {\n revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);\n }\n for (uint i; i < _addresses.length; i++) {\n LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);\n }\n }\n}\n" + }, + "contracts/init/InitLibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitLibWarp {\n function init(address weth, address permit2) public {\n LibWarp.State storage s = LibWarp.state();\n\n s.weth = IWETH(weth);\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/init/InitUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibUniV2Router} from '../libraries/LibUniV2Router.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\ncontract InitUniV2Router {\n function init(address uniswapV2Router02, address uniswapV2Factory, address permit2) public {\n LibUniV2Router.DiamondStorage storage s = LibUniV2Router.diamondStorage();\n\n if (!s.isInitialized) {\n s.isInitialized = true;\n s.uniswapV2router02 = IUniswapV2Router02(uniswapV2Router02);\n s.weth = IWETH(s.uniswapV2router02.WETH());\n }\n\n s.uniswapV2Factory = uniswapV2Factory;\n s.permit2 = IPermit2(permit2);\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Factory.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/ICurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface ICurve {\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint48 deadline;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n function curveExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IDiamondLoupe.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n /// These functions are expected to be called frequently\n /// by tools.\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /// @notice Gets all facet addresses and their four byte function selectors.\n /// @return facets_ Facet\n function facets() external view returns (Facet[] memory facets_);\n\n /// @notice Gets all the function selectors supported by a specific facet.\n /// @param _facet The facet address.\n /// @return facetFunctionSelectors_\n function facetFunctionSelectors(\n address _facet\n ) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n /// @notice Get all the facet addresses used by a diamond.\n /// @return facetAddresses_\n function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n /// @notice Gets the facet that supports the given selector.\n /// @dev If facet is not found return address(0).\n /// @param _functionSelector The function selector.\n /// @return facetAddress_ The facet address.\n function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n" + }, + "contracts/interfaces/IERC173.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-173 Contract Ownership Standard\n/// Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n /// @dev This emits when ownership of a contract changes.\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /// @notice Get the address of the owner\n /// @return owner_ The address of the owner.\n function owner() external view returns (address owner_);\n\n /// @notice Set the address of the new owner of the contract\n /// @dev Set _newOwner to address(0) to renounce any ownership.\n /// @param _newOwner The address of the new owner of the contract\n function transferOwnership(address _newOwner) external;\n}\n" + }, + "contracts/interfaces/IKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {LibDiamond} from '../libraries/LibDiamond.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Errors} from '../libraries/Errors.sol';\n\ninterface IKitty {\n event PartnerWithdraw(address indexed partner, address indexed token, uint256 amount);\n\n function partnerTokens(address partner) external view returns (address[] memory tokens_);\n\n function partnerTokenBalance(address partner, address token) external view returns (uint256);\n\n function partnerWithdraw(address token) external;\n\n function ownerWithdraw(address token, uint256 amount, address payable to) external;\n}\n" + }, + "contracts/interfaces/IUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n uint16[] poolFeesBps;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n address pool;\n uint16 feeBps;\n uint16 slippageBps;\n address partner;\n address tokenIn;\n address tokenOut;\n uint16 poolFeeBps;\n uint48 deadline;\n }\n\n function uniswapV2LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV2Router {\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] path;\n }\n\n struct ExactInputSingleParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippage;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address tokenIn;\n address tokenOut;\n }\n\n function uniswapV2ExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV2ExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IUniV3Like {\n error InsufficienTokensDelivered();\n error DeadlineExpired();\n error InsufficientOutputAmount();\n error EthTransferFailed();\n error IncorrectEthValue();\n\n struct ExactInputParams {\n uint256 amountIn;\n uint256 amountOut;\n address recipient;\n uint16 slippageBps;\n uint16 feeBps;\n uint48 deadline;\n address partner;\n address[] tokens;\n address[] pools;\n }\n\n struct ExactInputSingleParams {\n address recipient;\n address partner;\n uint16 feeBps;\n uint16 slippageBps;\n uint256 amountIn;\n uint48 deadline;\n address tokenIn;\n address tokenOut;\n uint256 amountOut;\n address pool;\n }\n\n function uniswapV3LikeExactInputSingle(\n ExactInputSingleParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n\n function uniswapV3LikeExactInput(\n ExactInputParams memory params,\n PermitParams calldata permit\n ) external payable returns (uint256 amountOut);\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error IncorrectEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedValueAndTokenCombination();\n error UnexpectedPayerForWrap();\n error EthNotSupportedForWarp();\n error DeadlineExpired();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nabstract contract Errors {\n error AlreadyInitialized();\n error EthTransferFailed();\n error IncorrectEthValue();\n error ZeroAmountOut();\n error InsufficientOutputAmount();\n error DeadlineExpired();\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Router.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\nimport {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibUniV2Router {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.storage.LibUniV2Router');\n\n struct DiamondStorage {\n bool isInitialized;\n IWETH weth;\n IUniswapV2Router02 uniswapV2router02;\n address uniswapV2Factory;\n IPermit2 permit2;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage s) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n\n assembly {\n s.slot := position\n }\n }\n\n // calculates the CREATE2 address for a pair without making any external calls\n // NOTE: Modified to work with newer Solidity\n function pairFor(\n address factory,\n address tokenA,\n address tokenB\n ) internal pure returns (address pair) {\n if (tokenA > tokenB) {\n (tokenA, tokenB) = (tokenB, tokenA);\n }\n\n pair = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(tokenA, tokenB)),\n hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash\n )\n )\n )\n )\n );\n }\n\n function getPairsAndAmountsFromPath(\n address factory,\n uint256 amountIn,\n address[] memory path\n ) internal view returns (address[] memory pairs, uint256[] memory amounts) {\n uint256 pathLengthMinusOne = path.length - 1;\n\n pairs = new address[](pathLengthMinusOne);\n amounts = new uint256[](path.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < pathLengthMinusOne; ) {\n address token0 = path[index];\n address token1 = path[index + 1];\n\n pairs[index] = pairFor(factory, token0, token1);\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pairFor(factory, token0, token1))\n .getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn = ((amountIn * 997) * reserveOut) / ((reserveIn * 1000) + (amountIn * 997));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/SifiDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n*\n* Implementation of a diamond.\n/******************************************************************************/\n\nimport {LibDiamond} from './libraries/LibDiamond.sol';\nimport {IDiamondCut} from './interfaces/IDiamondCut.sol';\nimport {IDiamondLoupe} from './interfaces/IDiamondLoupe.sol';\n\ncontract SifiDiamond {\n constructor(address _contractOwner, address _diamondCutFacet) payable {\n LibDiamond.setContractOwner(_contractOwner);\n\n // Add the diamondCut external function from the diamondCutFacet\n IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n bytes4[] memory functionSelectors = new bytes4[](1);\n functionSelectors[0] = IDiamondCut.diamondCut.selector;\n cut[0] = IDiamondCut.FacetCut({\n facetAddress: _diamondCutFacet,\n action: IDiamondCut.FacetCutAction.Add,\n functionSelectors: functionSelectors\n });\n LibDiamond.diamondCut(cut, address(0), '');\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n fallback() external payable {\n LibDiamond.DiamondStorage storage ds;\n bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n // get diamond storage\n assembly {\n ds.slot := position\n }\n // get facet from function selector\n address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), 'Diamond: Function does not exist');\n // Execute external function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n receive() external payable {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/polygon/solcInputs/df6263755b6a66e75866b356448256e7.json b/packages/hardhat/deployments/polygon/solcInputs/df6263755b6a66e75866b356448256e7.json new file mode 100644 index 00000000..958f2b3a --- /dev/null +++ b/packages/hardhat/deployments/polygon/solcInputs/df6263755b6a66e75866b356448256e7.json @@ -0,0 +1,119 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\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 /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}\n" + }, + "contracts/facets/WarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {LibWarp} from '../libraries/LibWarp.sol';\nimport {LibKitty} from '../libraries/LibKitty.sol';\nimport {Stream} from '../libraries/Stream.sol';\nimport {LibUniV2Like} from '../libraries/LibUniV2Like.sol';\nimport {IUniswapV2Pair} from '../interfaces/external/IUniswapV2Pair.sol';\nimport {IWarpLink} from '../interfaces/IWarpLink.sol';\nimport {LibUniV3Like} from '../libraries/LibUniV3Like.sol';\nimport {IUniV3Callback} from '../interfaces/IUniV3Callback.sol';\nimport {IUniswapV3Pool} from '../interfaces/external/IUniswapV3Pool.sol';\nimport {LibCurve} from '../libraries/LibCurve.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IAllowanceTransfer} from '../interfaces/external/IAllowanceTransfer.sol';\nimport {PermitParams} from '../libraries/PermitParams.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nabstract contract WarpLinkCommandTypes {\n uint256 internal constant COMMAND_TYPE_WRAP = 1;\n uint256 internal constant COMMAND_TYPE_UNWRAP = 2;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE = 3;\n uint256 internal constant COMMAND_TYPE_SPLIT = 4;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT = 5;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE = 6;\n uint256 internal constant COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT = 7;\n uint256 internal constant COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE = 8;\n uint256 internal constant COMMAND_TYPE_JUMP_STARGATE = 9;\n}\n\ncontract WarpLink is IWarpLink, WarpLinkCommandTypes {\n using SafeERC20 for IERC20;\n using Stream for uint256;\n\n struct WarpUniV2LikeWarpSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpUniV2LikeExactInputParams {\n // NOTE: Excluding the first token\n address[] tokens;\n address[] pools;\n uint16[] poolFeesBps;\n }\n\n struct WarpUniV3LikeExactInputSingleParams {\n address tokenOut;\n address pool;\n bool zeroForOne; // tokenIn < tokenOut\n uint16 poolFeeBps;\n }\n\n struct WarpCurveExactInputSingleParams {\n address tokenOut;\n address pool;\n uint8 tokenIndexIn;\n uint8 tokenIndexOut;\n uint8 kind;\n bool underlying;\n }\n\n struct JumpStargateParams {\n uint16 dstChainId;\n uint256 srcPoolId;\n uint256 dstPoolId;\n }\n\n struct TransientState {\n address paramPartner;\n uint16 paramFeeBps;\n address paramRecipient;\n uint256 paramAmountOut;\n uint16 paramSlippageBps;\n uint256 amount;\n address payer;\n address token;\n uint48 deadline;\n /**\n * 0 or 1\n */\n uint256 jumped;\n /**\n * The amount of native value not spent. The native value starts off as\n * `msg.value - params.amount` and is decreased by spending money on jumps.\n *\n * Any leftover native value is returned to `msg.sender`\n */\n uint256 nativeValueRemaining;\n }\n\n function processSplit(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 parts = stream.readUint8();\n uint256 amountRemaining = t.amount;\n uint256 amountOutSum;\n\n if (parts < 2) {\n revert NotEnoughParts();\n }\n\n // Store the token out for the previous part to ensure every part has the same output token\n address firstPartTokenOut;\n address firstPartPayerOut;\n\n for (uint256 partIndex; partIndex < parts; ) {\n // TODO: Unchecked?\n // For the last part, use the remaining amount. Else read the % from the stream\n uint256 partAmount = partIndex < parts - 1\n ? (t.amount * stream.readUint16()) / 10_000\n : amountRemaining;\n\n if (partAmount > amountRemaining) {\n revert InsufficientAmountRemaining();\n }\n\n amountRemaining -= partAmount;\n\n TransientState memory tPart;\n\n tPart.amount = partAmount;\n tPart.payer = t.payer;\n tPart.token = t.token;\n\n tPart = engageInternal(stream, tPart);\n\n if (tPart.jumped == 1) {\n revert IllegalJumpInSplit();\n }\n\n if (partIndex == 0) {\n firstPartPayerOut = tPart.payer;\n firstPartTokenOut = tPart.token;\n } else {\n if (tPart.token != firstPartTokenOut) {\n revert InconsistentPartTokenOut();\n }\n\n if (tPart.payer != firstPartPayerOut) {\n revert InconsistentPartPayerOut();\n }\n }\n\n // NOTE: Checked\n amountOutSum += tPart.amount;\n\n unchecked {\n partIndex++;\n }\n }\n\n t.payer = firstPartPayerOut;\n t.token = firstPartTokenOut;\n t.amount = amountOutSum;\n\n return t;\n }\n\n /**\n * Wrap ETH into WETH using the WETH contract\n *\n * The ETH must already be in this contract\n *\n * The next token will be WETH, with the amount and payer unchanged\n */\n function processWrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(0)) {\n revert UnexpectedTokenForWrap();\n }\n\n if (t.payer != address(this)) {\n // It's not possible to move a user's ETH\n revert UnexpectedPayerForWrap();\n }\n\n t.token = address(s.weth);\n\n s.weth.deposit{value: t.amount}();\n\n return t;\n }\n\n /**\n * Unwrap WETH into ETH using the WETH contract\n *\n * The payer can be the sender or this contract. After this operation, the\n * token will be ETH (0) and the amount will be unchanged. The next payer\n * will be this contract.\n */\n function processUnwrap(TransientState memory t) internal returns (TransientState memory) {\n LibWarp.State storage s = LibWarp.state();\n\n if (t.token != address(s.weth)) {\n revert UnexpectedTokenForUnwrap();\n }\n\n address prevPayer = t.payer;\n bool shouldMoveTokensFirst = prevPayer != address(this);\n\n if (shouldMoveTokensFirst) {\n t.payer = address(this);\n }\n\n t.token = address(0);\n\n if (shouldMoveTokensFirst) {\n s.permit2.transferFrom(prevPayer, address(this), (uint160)(t.amount), address(s.weth));\n }\n\n s.weth.withdraw(t.amount);\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V2-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n * - zeroForOne (0 or 1, uint8)\n * - poolFeeBps (uint16)\n */\n function processWarpUniV2LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n WarpUniV2LikeWarpSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.zeroForOne = stream.readUint8() == 1;\n params.poolFeeBps = stream.readUint16();\n\n if (t.payer == address(this)) {\n // Transfer tokens to the pool\n IERC20(t.token).safeTransfer(params.pool, t.amount);\n } else {\n // Transfer tokens from the sender to the pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pool, (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(params.pool).getReserves();\n\n if (!params.zeroForOne) {\n // Token in > token out\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n // For 30 bps, multiply by 997\n uint256 feeFactor = 10_000 - params.poolFeeBps;\n\n t.amount =\n ((t.amount * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (t.amount * feeFactor));\n }\n\n // NOTE: This check can be avoided if the factory is trusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n IUniswapV2Pair(params.pool).swap(\n params.zeroForOne ? 0 : t.amount,\n params.zeroForOne ? t.amount : 0,\n address(this),\n ''\n );\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V2-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n * - pool fees (uint16 0, uint16 1, uint16 pool length - 1)\n */\n function processWarpUniV2LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n params.tokens = new address[](poolLength + 1);\n\n // The params will contain all tokens including the first to remain compatible\n // with the LibUniV2Like library's getAmountsOut function\n params.tokens[0] = t.token;\n\n for (uint256 index; index < poolLength; ) {\n params.tokens[index + 1] = stream.readAddress();\n\n unchecked {\n index++;\n }\n }\n\n params.pools = stream.readAddresses(poolLength);\n params.poolFeesBps = stream.readUint16s(poolLength);\n\n uint256 tokenOutBalancePrev = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n uint256[] memory amounts = LibUniV2Like.getAmountsOut(\n params.poolFeesBps,\n t.amount,\n params.tokens,\n params.pools\n );\n\n if (t.payer == address(this)) {\n // Transfer tokens from this contract to the first pool\n IERC20(t.token).safeTransfer(params.pools[0], t.amount);\n } else {\n // Transfer tokens from the sender to the first pool\n LibWarp.state().permit2.transferFrom(t.payer, params.pools[0], (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Same as UniV2Like\n for (uint index; index < poolLength; ) {\n uint256 indexPlusOne = index + 1;\n bool zeroForOne = params.tokens[index] < params.tokens[indexPlusOne] ? true : false;\n address to = index < params.tokens.length - 2 ? params.pools[indexPlusOne] : address(this);\n\n IUniswapV2Pair(params.pools[index]).swap(\n zeroForOne ? 0 : amounts[indexPlusOne],\n zeroForOne ? amounts[indexPlusOne] : 0,\n to,\n ''\n );\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(params.tokens[poolLength]).balanceOf(address(this));\n\n t.amount = amounts[amounts.length - 1];\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokens[poolLength];\n\n return t;\n }\n\n /**\n * Warp a single token in a Uniswap V3-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpUniV3LikeExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV3LikeExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n\n if (t.token == address(0)) {\n revert NativeTokenNotSupported();\n }\n\n // NOTE: The pool is untrusted\n uint256 balancePrev = IERC20(params.tokenOut).balanceOf(address(this));\n\n bool zeroForOne = t.token < params.tokenOut;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: t.token, amount: t.amount})\n );\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(params.pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n uint256 balanceNext = IERC20(params.tokenOut).balanceOf(address(this));\n\n if (balanceNext < balancePrev || balanceNext < balancePrev + t.amount) {\n revert InsufficientTokensDelivered();\n }\n\n t.token = params.tokenOut;\n\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n\n return t;\n }\n\n /**\n * Warp multiple tokens in a series of Uniswap V3-like pools\n *\n * Since the pools are not trusted, the balance of `params.tokenOut` is checked\n * before the first swap and after the last swap to ensure the correct amount\n * was delivered.\n *\n * The payer can be the sender or this contract. The token must not be ETH (0).\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the last swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - pool length (uint8)\n * - tokens (address 0, address 1, address pool length - 1) excluding the first\n * - pools (address 0, address 1, address pool length - 1)\n */\n function processWarpUniV3LikeExactInput(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpUniV2LikeExactInputParams memory params;\n\n uint256 poolLength = stream.readUint8();\n\n // The first token is not included\n params.tokens = stream.readAddresses(poolLength);\n params.pools = stream.readAddresses(poolLength);\n\n address lastToken = params.tokens[poolLength - 1];\n\n uint256 tokenOutBalancePrev = IERC20(lastToken).balanceOf(address(this));\n\n for (uint index; index < poolLength; ) {\n address tokenIn = index == 0 ? t.token : params.tokens[index - 1]; // TOOD: unchecked\n t.token = params.tokens[index];\n bool zeroForOne = tokenIn < t.token;\n\n LibUniV3Like.beforeCallback(\n LibUniV3Like.CallbackState({payer: t.payer, token: tokenIn, amount: t.amount})\n );\n\n if (index == 0) {\n // Update the payer to this contract\n // TODO: Compare check-and-set vs set\n t.payer = address(this);\n }\n\n address pool = params.pools[index];\n\n if (zeroForOne) {\n (, int256 amountOutSigned) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MIN_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n } else {\n (int256 amountOutSigned, ) = IUniswapV3Pool(pool).swap(\n address(this),\n zeroForOne,\n int256(t.amount),\n LibUniV3Like.MAX_SQRT_RATIO,\n ''\n );\n\n t.amount = uint256(-amountOutSigned);\n }\n\n LibUniV3Like.afterCallback();\n\n unchecked {\n index++;\n }\n }\n\n uint256 nextTokenOutBalance = IERC20(t.token).balanceOf(address(this));\n\n if (\n // TOOD: Is this overflow check necessary?\n nextTokenOutBalance < tokenOutBalancePrev ||\n nextTokenOutBalance < tokenOutBalancePrev + t.amount\n ) {\n revert InsufficientTokensDelivered();\n }\n\n return t;\n }\n\n /**\n * Warp a single token in a Curve-like pool\n *\n * Since the pool is not trusted, the amount out is checked before\n * and after the swap to ensure the correct amount was delivered.\n *\n * The payer can be the sender or this contract. The token may be ETH (0)\n *\n * After this operation, the token will be `params.tokenOut` and the amount will\n * be the output of the swap. The next payer will be this contract.\n *\n * Params are read from the stream as:\n * - tokenOut (address)\n * - pool (address)\n */\n function processWarpCurveExactInputSingle(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n WarpCurveExactInputSingleParams memory params;\n\n params.tokenOut = stream.readAddress();\n params.pool = stream.readAddress();\n params.tokenIndexIn = stream.readUint8();\n params.tokenIndexOut = stream.readUint8();\n params.kind = stream.readUint8();\n params.underlying = stream.readUint8() == 1;\n\n // NOTE: The pool is untrusted\n bool isFromEth = t.token == address(0);\n bool isToEth = params.tokenOut == address(0);\n\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n uint256 balancePrev = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n if (!isFromEth) {\n // TODO: Is this necessary to support USDT?\n IERC20(t.token).forceApprove(params.pool, t.amount);\n }\n\n LibCurve.exchange({\n kind: params.kind,\n underlying: params.underlying,\n pool: params.pool,\n eth: isFromEth ? t.amount : 0,\n i: params.tokenIndexIn,\n j: params.tokenIndexOut,\n dx: t.amount,\n // NOTE: There is no need to set a min out since the balance will be verified\n min_dy: 0\n });\n\n uint256 balanceNext = isToEth\n ? address(this).balance\n : IERC20(params.tokenOut).balanceOf(address(this));\n\n t.token = params.tokenOut;\n t.amount = balanceNext - balancePrev;\n\n return t;\n }\n\n /**\n * Jump to another chain using the Stargate bridge\n *\n * The token must not be ETH (0)\n *\n * After this operation, the token will be unchanged and `t.amount` will\n * be how much was sent. `t.jumped` will be set to `1` to indicate\n * that no more commands should be run\n *\n * The user may construct a command where `srcPoolId` is not for `t.token`. This is harmless\n * because only `t.token` can be moved by Stargate.\n *\n * This command must not run inside of a split.\n *\n * A bridge fee must be paid in the native token. This fee is determined with\n * `IStargateRouter.quoteLayerZeroFee`\n *\n * The value for `t.token` remains the same and is not chained.\n *\n * Params are read from the stream as:\n * - dstChainId (uint16)\n * - srcPoolId (uint8)\n * - dstPoolId (uint8)\n */\n function processJumpStargate(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n if (t.token == address(0)) {\n // NOTE: There is a WETH pool\n revert NativeTokenNotSupported();\n }\n\n JumpStargateParams memory params;\n params.dstChainId = stream.readUint16();\n params.srcPoolId = stream.readUint8();\n params.dstPoolId = stream.readUint8();\n\n // NOTE: It is not possible to know how many tokens were delivered. Therfore positive slippage\n // is never charged\n t.amount = LibKitty.calculateAndRegisterFee(\n t.paramPartner,\n t.token,\n t.paramFeeBps,\n t.amount,\n t.amount\n );\n\n // Enforce minimum amount/max slippage\n if (t.amount < LibWarp.applySlippage(t.paramAmountOut, t.paramSlippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.token != address(0)) {\n if (t.payer != address(this)) {\n // Transfer tokens from the sender to this contract\n LibWarp.state().permit2.transferFrom(t.payer, address(this), (uint160)(t.amount), t.token);\n\n // Update the payer to this contract\n t.payer = address(this);\n }\n\n // Allow Stargate to transfer the tokens\n IERC20(t.token).forceApprove(address(LibWarp.state().stargateRouter), t.amount);\n }\n\n t.jumped = 1;\n\n LibWarp.state().stargateRouter.swap{value: t.nativeValueRemaining}({\n _dstChainId: params.dstChainId,\n _srcPoolId: params.srcPoolId,\n _dstPoolId: params.dstPoolId,\n // NOTE: There is no guarantee that `msg.sender` can handle receiving tokens/ETH\n _refundAddress: payable(address(this)),\n _amountLD: t.amount,\n // Max 5% slippage\n _minAmountLD: (t.amount * 95) / 100,\n _lzTxParams: IStargateRouter.lzTxObj({\n dstGasForCall: 0,\n dstNativeAmount: 0,\n dstNativeAddr: ''\n }),\n _to: abi.encodePacked(t.paramRecipient),\n _payload: ''\n });\n\n t.nativeValueRemaining = 0;\n\n return t;\n }\n\n function engageInternal(\n uint256 stream,\n TransientState memory t\n ) internal returns (TransientState memory) {\n uint256 commandCount = stream.readUint8();\n\n // TODO: End of stream check?\n for (uint256 commandIndex; commandIndex < commandCount; commandIndex++) {\n // TODO: Unchecked?\n uint256 commandType = stream.readUint8();\n\n if (commandType == COMMAND_TYPE_WRAP) {\n t = processWrap(t);\n } else if (commandType == COMMAND_TYPE_UNWRAP) {\n t = processUnwrap(t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV2LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_SPLIT) {\n t = processSplit(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V2_LIKE_EXACT_INPUT) {\n t = processWarpUniV2LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT_SINGLE) {\n t = processWarpUniV3LikeExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_UNI_V3_LIKE_EXACT_INPUT) {\n t = processWarpUniV3LikeExactInput(stream, t);\n } else if (commandType == COMMAND_TYPE_WARP_CURVE_EXACT_INPUT_SINGLE) {\n t = processWarpCurveExactInputSingle(stream, t);\n } else if (commandType == COMMAND_TYPE_JUMP_STARGATE) {\n if (commandIndex != commandCount - 1) {\n revert JumpMustBeLastCommand();\n }\n\n t = processJumpStargate(stream, t);\n } else {\n revert UnhandledCommand();\n }\n }\n\n return t;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable {\n if (block.timestamp > params.deadline) {\n revert DeadlineExpired();\n }\n\n TransientState memory t;\n t.paramPartner = params.partner;\n t.paramFeeBps = params.feeBps;\n t.paramRecipient = params.recipient;\n t.paramAmountOut = params.amountOut;\n t.amount = params.amountIn;\n t.token = params.tokenIn;\n t.deadline = params.deadline;\n\n if (params.tokenIn == address(0)) {\n if (msg.value < params.amountIn) {\n revert InsufficientEthValue();\n }\n\n t.nativeValueRemaining = msg.value - params.amountIn;\n\n // The ETH has already been moved to this contract\n t.payer = address(this);\n } else {\n // Tokens will initially moved from the sender\n t.payer = msg.sender;\n\n t.nativeValueRemaining = msg.value;\n\n // Permit tokens / set allowance\n LibWarp.state().permit2.permit(\n msg.sender,\n IAllowanceTransfer.PermitSingle({\n details: IAllowanceTransfer.PermitDetails({\n token: params.tokenIn,\n amount: (uint160)(params.amountIn),\n expiration: (uint48)(params.deadline),\n nonce: (uint48)(permit.nonce)\n }),\n spender: address(this),\n sigDeadline: (uint256)(params.deadline)\n }),\n permit.signature\n );\n }\n\n uint256 stream = Stream.createStream(params.commands);\n\n t = engageInternal(stream, t);\n\n uint256 amountOut = t.amount;\n address tokenOut = t.token;\n\n if (tokenOut != params.tokenOut) {\n revert UnexpectedTokenOut();\n }\n\n // Enforce minimum amount/max slippage\n if (amountOut < LibWarp.applySlippage(params.amountOut, params.slippageBps)) {\n revert InsufficientOutputAmount();\n }\n\n if (t.nativeValueRemaining > 0) {\n // TODO: Is this the correct recipient?\n payable(msg.sender).transfer(t.nativeValueRemaining);\n }\n\n if (t.jumped == 1) {\n // The coins have jumped away from this chain. Fees were collected before the jump\n return;\n }\n\n // Collect fees\n amountOut = LibKitty.calculateAndRegisterFee(\n params.partner,\n params.tokenOut,\n params.feeBps,\n params.amountOut,\n amountOut\n );\n\n // Deliver tokens\n if (tokenOut == address(0)) {\n payable(params.recipient).transfer(amountOut);\n } else {\n IERC20(tokenOut).safeTransfer(params.recipient, amountOut);\n }\n }\n}\n" + }, + "contracts/interfaces/external/IAllowanceTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\ninterface IAllowanceTransfer is IEIP712 {\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of the token\n address to;\n // the amount of the token\n uint160 amount;\n // the token to be transferred\n address token;\n }\n\n /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.\n /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]\n /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.\n function allowance(\n address user,\n address token,\n address spender\n ) external view returns (uint160 amount, uint48 expiration, uint48 nonce);\n\n /// @notice Approves the spender to use up to amount of the specified token up until the expiration\n /// @param token The token to approve\n /// @param spender The spender address to approve\n /// @param amount The approved amount of the token\n /// @param expiration The timestamp at which the approval is no longer valid\n /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n function approve(address token, address spender, uint160 amount, uint48 expiration) external;\n\n /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitSingle Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(\n address owner,\n PermitSingle memory permitSingle,\n bytes calldata signature\n ) external;\n\n /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature\n /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce\n /// @param owner The owner of the tokens being approved\n /// @param permitBatch Data signed over by the owner specifying the terms of approval\n /// @param signature The owner's signature over the permit data\n function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;\n\n /// @notice Transfer approved tokens from one address to another\n /// @param from The address to transfer from\n /// @param to The address of the recipient\n /// @param amount The amount of the token to transfer\n /// @param token The token address to transfer\n /// @dev Requires the from address to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(address from, address to, uint160 amount, address token) external;\n\n /// @notice Transfer approved tokens in a batch\n /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers\n /// @dev Requires the from addresses to have approved at least the desired amount\n /// of tokens to msg.sender.\n function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;\n\n /// @notice Enables performing a \"lockdown\" of the sender's Permit2 identity\n /// by batch revoking approvals\n /// @param approvals Array of approvals to revoke.\n function lockdown(TokenSpenderPair[] calldata approvals) external;\n\n /// @notice Invalidate nonces for a given (token, spender) pair\n /// @param token The token to invalidate nonces for\n /// @param spender The spender to invalidate nonces for\n /// @param newNonce The new nonce to set. Invalidates all nonces less than it.\n /// @dev Can't invalidate more than 2**16 nonces per transaction.\n function invalidateNonces(address token, address spender, uint48 newNonce) external;\n}\n" + }, + "contracts/interfaces/external/ICurvePool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n// Kind 1\n// Example v0.2.4 tripool (stables)\n// See https://etherscan.io/address/0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7\ninterface ICurvePoolKind1 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n\n function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable;\n}\n\n// Kind 2\n// Example v0.2.8, Stableswap, v0.2.5 Curve GUSD Metapool\n// See https://etherscan.io/address/0xdc24316b9ae028f1497c275eb9192a3ea0f67022\ninterface ICurvePoolKind2 {\n function coins(uint256 index) external view returns (address);\n\n function base_coins(uint256 index) external view returns (address);\n\n // 0x3df02124\n function exchange(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n int128 i,\n int128 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n\n// Kind 3\n// Example v0.3.0, \"# EUR/3crv pool where 3crv is _second_, not first\"\n// See https://etherscan.io/address/0x5D0F47B32fDd343BfA74cE221808e2abE4A53827\n// NOTE: This contract has an `exchange_underlying` with a receiver also\ninterface ICurvePoolKind3 {\n function coins(uint256 index) external view returns (address);\n\n function underlying_coins(uint256 index) external view returns (address);\n\n function exchange(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n\n function exchange_underlying(\n uint256 i,\n uint256 j,\n uint256 dx,\n uint256 min_dy\n ) external payable returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IEIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/interfaces/external/IPermit2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ISignatureTransfer} from './ISignatureTransfer.sol';\nimport {IAllowanceTransfer} from './IAllowanceTransfer.sol';\n\n/// @notice Permit2 handles signature-based transfers in SignatureTransfer and allowance-based transfers in AllowanceTransfer.\n/// @dev Users must approve Permit2 before calling any of the transfer functions.\ninterface IPermit2 is ISignatureTransfer, IAllowanceTransfer {\n // IPermit2 unifies the two interfaces so users have maximal flexibility with their approval.\n}\n" + }, + "contracts/interfaces/external/ISignatureTransfer.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IEIP712} from './IEIP712.sol';\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers multiple tokens using a signed permit message\n /// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails Specifies the recipient and requested amount for the token transfer\n /// @param witness Extra data to include when checking the user signature\n /// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash\n /// @param signature The signature to verify\n function permitWitnessTransferFrom(\n PermitBatchTransferFrom memory permit,\n SignatureTransferDetails[] calldata transferDetails,\n address owner,\n bytes32 witness,\n string calldata witnessTypeString,\n bytes calldata signature\n ) external;\n\n /// @notice Invalidates the bits specified in mask for the bitmap at the word position\n /// @dev The wordPos is maxed at type(uint248).max\n /// @param wordPos A number to index the nonceBitmap at\n /// @param mask A bitmap masked against msg.sender's current bitmap at the word position\n function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;\n}\n" + }, + "contracts/interfaces/external/IStargateRouter.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IStargateRouter {\n struct lzTxObj {\n uint256 dstGasForCall;\n uint256 dstNativeAmount;\n bytes dstNativeAddr;\n }\n\n function swap(\n uint16 _dstChainId,\n uint256 _srcPoolId,\n uint256 _dstPoolId,\n address payable _refundAddress,\n uint256 _amountLD,\n uint256 _minAmountLD,\n lzTxObj memory _lzTxParams,\n bytes calldata _to,\n bytes calldata _payload\n ) external payable;\n}\n" + }, + "contracts/interfaces/external/IUniswapV2Pair.sol": { + "content": "pragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n function getReserves()\n external\n view\n returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n}\n" + }, + "contracts/interfaces/external/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniswapV3Pool {\n function swap(\n address recipient,\n bool zeroForOne,\n int256 amountSpecified,\n uint160 sqrtPriceLimitX96,\n bytes calldata data\n ) external returns (int256 amount0, int256 amount1);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function liquidity() external view returns (uint128);\n}\n" + }, + "contracts/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n /// @param _init The address of the contract or facet to execute _calldata\n /// @param _calldata A function call, including function selector and arguments\n /// _calldata is executed with delegatecall on _init\n function diamondCut(\n FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n" + }, + "contracts/interfaces/IUniV3Callback.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IUniV3Callback {\n error CallbackInactive();\n}\n" + }, + "contracts/interfaces/IWarpLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {PermitParams} from '../libraries/PermitParams.sol';\n\ninterface IWarpLink {\n error UnhandledCommand();\n error InsufficientEthValue();\n error InsufficientOutputAmount();\n error InsufficientTokensDelivered();\n error UnexpectedTokenForWrap();\n error UnexpectedTokenForUnwrap();\n error UnexpectedTokenOut();\n error InsufficientAmountRemaining();\n error NotEnoughParts();\n error InconsistentPartTokenOut();\n error InconsistentPartPayerOut();\n error UnexpectedPayerForWrap();\n error NativeTokenNotSupported();\n error DeadlineExpired();\n error IllegalJumpInSplit();\n error JumpMustBeLastCommand();\n\n struct Params {\n address partner;\n uint16 feeBps;\n /**\n * How much below `amountOut` the user will accept\n */\n uint16 slippageBps;\n address recipient;\n address tokenIn;\n address tokenOut;\n uint256 amountIn;\n /**\n * The amount the user was quoted\n */\n uint256 amountOut;\n uint48 deadline;\n bytes commands;\n }\n\n function warpLinkEngage(Params memory params, PermitParams calldata permit) external payable;\n}\n" + }, + "contracts/libraries/LibCurve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {ICurvePoolKind1, ICurvePoolKind2, ICurvePoolKind3} from '../interfaces/external/ICurvePool.sol';\n\nlibrary LibCurve {\n error UnhandledPoolKind();\n\n function exchange(\n uint8 kind,\n bool underlying,\n address pool,\n uint256 eth,\n uint8 i,\n uint8 j,\n uint256 dx,\n uint256 min_dy\n ) internal {\n if (kind == 1) {\n if (underlying) {\n ICurvePoolKind1(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind1(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 2) {\n if (underlying) {\n ICurvePoolKind2(pool).exchange_underlying{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n } else {\n ICurvePoolKind2(pool).exchange{value: eth}(\n int128(uint128(i)),\n int128(uint128(j)),\n dx,\n min_dy\n );\n }\n } else if (kind == 3) {\n if (underlying) {\n ICurvePoolKind3(pool).exchange_underlying{value: eth}(uint256(i), uint256(j), dx, min_dy);\n } else {\n ICurvePoolKind3(pool).exchange{value: eth}(uint256(i), uint256(j), dx, min_dy);\n }\n } else {\n revert UnhandledPoolKind();\n }\n }\n}\n" + }, + "contracts/libraries/LibDiamond.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/******************************************************************************\\\n* Author: Nick Mudge (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from '../interfaces/IDiamondCut.sol';\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nerror InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);\n\nlibrary LibDiamond {\n bytes32 constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage');\n\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n }\n\n struct DiamondStorage {\n // maps function selector to the facet address and\n // the position of the selector in the facetFunctionSelectors.selectors array\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n // facet addresses\n address[] facetAddresses;\n address contractOwner;\n }\n\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n bytes32 position = DIAMOND_STORAGE_POSITION;\n assembly {\n ds.slot := position\n }\n }\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n function setContractOwner(address _newOwner) internal {\n DiamondStorage storage ds = diamondStorage();\n address previousOwner = ds.contractOwner;\n ds.contractOwner = _newOwner;\n emit OwnershipTransferred(previousOwner, _newOwner);\n }\n\n function contractOwner() internal view returns (address contractOwner_) {\n contractOwner_ = diamondStorage().contractOwner;\n }\n\n function enforceIsContractOwner() internal view {\n require(msg.sender == diamondStorage().contractOwner, 'LibDiamond: Must be contract owner');\n }\n\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n // Internal function version of diamondCut\n function diamondCut(\n IDiamondCut.FacetCut[] memory _diamondCut,\n address _init,\n bytes memory _calldata\n ) internal {\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(\n _diamondCut[facetIndex].facetAddress,\n _diamondCut[facetIndex].functionSelectors\n );\n } else {\n revert('LibDiamondCut: Incorrect FacetCutAction');\n }\n }\n emit DiamondCut(_diamondCut, _init, _calldata);\n initializeDiamondCut(_init, _calldata);\n }\n\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress == address(0),\n \"LibDiamondCut: Can't add function that already exists\"\n );\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n );\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(ds, _facetAddress);\n }\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n require(\n oldFacetAddress != _facetAddress,\n \"LibDiamondCut: Can't replace function with same function\"\n );\n removeFunction(ds, oldFacetAddress, selector);\n addFunction(ds, selector, selectorPosition, _facetAddress);\n selectorPosition++;\n }\n }\n\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');\n DiamondStorage storage ds = diamondStorage();\n // if function does not exist then do nothing and return\n require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\n bytes4 selector = _functionSelectors[selectorIndex];\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(ds, oldFacetAddress, selector);\n }\n }\n\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n ds.facetAddresses.push(_facetAddress);\n }\n\n function addFunction(\n DiamondStorage storage ds,\n bytes4 _selector,\n uint96 _selectorPosition,\n address _facetAddress\n ) internal {\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n }\n\n function removeFunction(\n DiamondStorage storage ds,\n address _facetAddress,\n bytes4 _selector\n ) internal {\n require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n // an immutable function is a function defined directly in a diamond\n require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n uint256 lastSelectorPosition = ds\n .facetFunctionSelectors[_facetAddress]\n .functionSelectors\n .length - 1;\n // if not the same then replace _selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n lastSelectorPosition\n ];\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(\n selectorPosition\n );\n }\n // delete the last selector\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n delete ds.selectorToFacetAndPosition[_selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n ds.facetAddresses.pop();\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n }\n }\n\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n if (_init == address(0)) {\n return;\n }\n enforceHasContractCode(_init, 'LibDiamondCut: _init address has no code');\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\n if (!success) {\n if (error.length > 0) {\n // bubble up error\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(error)\n revert(add(32, error), returndata_size)\n }\n } else {\n revert InitializationFunctionReverted(_init, _calldata);\n }\n }\n }\n\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize > 0, _errorMessage);\n }\n}\n" + }, + "contracts/libraries/LibKitty.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\nimport {LibDiamond} from './LibDiamond.sol';\n\nlibrary LibKitty {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /**\n * The swap fee is over the maximum allowed\n */\n error FeeTooHigh(uint16 maxFeeBps);\n\n event CollectedFee(\n address indexed partner,\n address indexed token,\n uint256 partnerFee,\n uint256 diamondFee\n );\n\n struct State {\n /**\n * Set of partner balances. An address is added when the partner is first credited\n */\n EnumerableSet.AddressSet partners;\n /**\n * Set of tokens a partner has ever received fees in. The ETH token address zero is not included.\n * Tokens are not removed from this set when a partner withdraws.\n * Mapping: Partner -> token set\n */\n mapping(address => EnumerableSet.AddressSet) partnerTokens;\n /**\n * Token balances per partner\n * Mapping: Partner -> token -> balance\n */\n mapping(address => mapping(address => uint256)) partnerBalances;\n /**\n * Total balances per token for all partners.\n * Mapping: token -> balance\n */\n mapping(address => uint256) partnerBalancesTotal;\n }\n\n uint16 private constant MAX_FEE_BPS = 2_000;\n\n function state() internal pure returns (State storage s) {\n bytes32 storagePosition = keccak256('diamond.storage.LibKitty');\n\n assembly {\n s.slot := storagePosition\n }\n }\n\n /**\n * By using a library function we ensure that the storage used by the library is whichever contract\n * is calling this function\n */\n function registerCollectedFee(\n address partner,\n address token,\n uint256 partnerFee,\n uint256 diamondFee\n ) internal {\n State storage s = state();\n\n if (token != address(0)) {\n s.partnerTokens[partner].add(token);\n }\n\n s.partners.add(partner);\n\n unchecked {\n s.partnerBalances[partner][token] += partnerFee;\n s.partnerBalancesTotal[token] += partnerFee;\n }\n\n emit CollectedFee(partner, token, partnerFee, diamondFee);\n }\n\n function calculateAndRegisterFee(\n address partner,\n address token,\n uint16 feeBps,\n uint256 amountOutQuoted,\n uint256 amountOutActual\n ) internal returns (uint256 amountOutUser_) {\n if (feeBps > MAX_FEE_BPS) {\n revert FeeTooHigh(MAX_FEE_BPS);\n }\n\n unchecked {\n uint256 feeTotal;\n uint256 feeBasis = amountOutActual;\n\n if (amountOutActual > amountOutQuoted) {\n // Positive slippage\n feeTotal = amountOutActual - amountOutQuoted;\n\n // Change the fee basis for use below\n feeBasis = amountOutQuoted;\n }\n\n // Fee taken from actual\n feeTotal += (feeBasis * feeBps) / 10_000;\n\n // If a partner is set, split the fee in half\n uint256 feePartner = partner == address(0) ? 0 : (feeTotal * 50) / 100;\n uint256 feeDiamond = feeTotal - feePartner;\n\n if (feeDiamond > 0) {\n registerCollectedFee(partner, token, feePartner, feeDiamond);\n }\n\n return amountOutActual - feeTotal;\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV2Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IUniswapV2Pair} from 'contracts/interfaces/external/IUniswapV2Pair.sol';\n\nlibrary LibUniV2Like {\n function getAmountsOut(\n uint16[] memory poolFeesBps,\n uint256 amountIn,\n address[] memory tokens,\n address[] memory pools\n ) internal view returns (uint256[] memory amounts) {\n uint256 poolLength = pools.length;\n\n amounts = new uint256[](tokens.length);\n amounts[0] = amountIn;\n\n for (uint256 index; index < poolLength; ) {\n address token0 = tokens[index];\n address token1 = tokens[index + 1];\n\n // For 30 bps, multiply by 9970\n uint256 feeFactor = 10_000 - poolFeesBps[index];\n\n (uint256 reserveIn, uint256 reserveOut, ) = IUniswapV2Pair(pools[index]).getReserves();\n\n if (token0 > token1) {\n (reserveIn, reserveOut) = (reserveOut, reserveIn);\n }\n\n unchecked {\n amountIn =\n ((amountIn * feeFactor) * reserveOut) /\n ((reserveIn * 10_000) + (amountIn * feeFactor));\n }\n\n // Recycling `amountIn`\n amounts[index + 1] = amountIn;\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + }, + "contracts/libraries/LibUniV3Like.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nlibrary LibUniV3Like {\n error CallbackAlreadyActive();\n error CallbackStillActive();\n\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibUniV3Like');\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;\n\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;\n\n struct CallbackState {\n uint256 amount;\n address payer;\n address token;\n }\n\n struct State {\n // TODO: Does this help by using `MSTORE8`?\n uint8 isActive;\n /**\n * Transient storage variable used in the callback\n */\n CallbackState callback;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function beforeCallback(CallbackState memory callback) internal {\n if (state().isActive == 1) {\n revert CallbackAlreadyActive();\n }\n\n state().isActive = 1;\n state().callback = callback;\n }\n\n function afterCallback() internal view {\n if (state().isActive == 1) {\n // The field is expected to be zeroed out by the callback\n revert CallbackStillActive();\n }\n }\n}\n" + }, + "contracts/libraries/LibWarp.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IWETH} from '@uniswap/v2-periphery/contracts/interfaces/IWETH.sol';\nimport {IPermit2} from '../interfaces/external/IPermit2.sol';\nimport {IStargateRouter} from '../interfaces/external/IStargateRouter.sol';\n\nlibrary LibWarp {\n bytes32 constant DIAMOND_STORAGE_SLOT = keccak256('diamond.storage.LibWarp');\n\n struct State {\n IWETH weth;\n IPermit2 permit2;\n IStargateRouter stargateRouter;\n }\n\n function state() internal pure returns (State storage s) {\n bytes32 slot = DIAMOND_STORAGE_SLOT;\n\n assembly {\n s.slot := slot\n }\n }\n\n function applySlippage(uint256 amount, uint16 slippage) internal pure returns (uint256) {\n return (amount * (10_000 - slippage)) / 10_000;\n }\n}\n" + }, + "contracts/libraries/PermitParams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nstruct PermitParams {\n uint256 nonce;\n bytes signature;\n}\n" + }, + "contracts/libraries/Stream.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * Stream reader\n *\n * Note that the stream position is always behind by one as per the\n * original implementation\n *\n * See https://github.com/sushiswap/sushiswap/blob/master/protocols/route-processor/contracts/InputStream.sol\n */\nlibrary Stream {\n function createStream(bytes memory data) internal pure returns (uint256 stream) {\n assembly {\n // Get a pointer to the next free memory\n stream := mload(0x40)\n\n // Move the free memory pointer forward by 64 bytes, since\n // this function will store 2 words (64 bytes) to memory.\n mstore(0x40, add(stream, 64))\n\n // Store a pointer to the data in the first word of the stream\n mstore(stream, data)\n\n // Store a pointer to the end of the data in the second word of the stream\n let length := mload(data)\n mstore(add(stream, 32), add(data, length))\n }\n }\n\n function isNotEmpty(uint256 stream) internal pure returns (bool) {\n uint256 pos;\n uint256 finish;\n assembly {\n pos := mload(stream)\n finish := mload(add(stream, 32))\n }\n return pos < finish;\n }\n\n function readUint8(uint256 stream) internal pure returns (uint8 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 1)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint16(uint256 stream) internal pure returns (uint16 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 2)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint24(uint256 stream) internal pure returns (uint24 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 3)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint32(uint256 stream) internal pure returns (uint32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 4)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint48(uint256 stream) internal pure returns (uint48 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 6)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint160(uint256 stream) internal pure returns (uint160 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readUint256(uint256 stream) internal pure returns (uint256 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes32(uint256 stream) internal pure returns (bytes32 res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 32)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readAddress(uint256 stream) internal pure returns (address res) {\n assembly {\n let pos := mload(stream)\n pos := add(pos, 20)\n res := mload(pos)\n mstore(stream, pos)\n }\n }\n\n function readBytes(uint256 stream) internal pure returns (bytes memory res) {\n assembly {\n let pos := mload(stream)\n res := add(pos, 32)\n let length := mload(res)\n mstore(stream, add(res, length))\n }\n }\n\n function readAddresses(\n uint256 stream,\n uint256 count\n ) internal pure returns (address[] memory res) {\n res = new address[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readAddress(stream);\n\n unchecked {\n index++;\n }\n }\n }\n\n function readUint16s(uint256 stream, uint256 count) internal pure returns (uint16[] memory res) {\n res = new uint16[](count);\n\n for (uint256 index; index < count; ) {\n res[index] = readUint16(stream);\n\n unchecked {\n index++;\n }\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "solidity-stringutils/=lib/solidity-stringutils/src/", + "@openzeppelin/=@openzeppelin/", + "@uniswap/=@uniswap/", + "hardhat-deploy/=hardhat-deploy/", + "hardhat/=hardhat/" + ] + } +} \ No newline at end of file diff --git a/packages/hardhat/package.json b/packages/hardhat/package.json index 232e5003..d8bcb29a 100644 --- a/packages/hardhat/package.json +++ b/packages/hardhat/package.json @@ -1,6 +1,6 @@ { "name": "@sifi/hardhat", - "version": "1.11.0", + "version": "1.12.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": {